还没有写完,后续会添加reference,解释以及例子
Q1: 表中相邻两行求差
# the difference between two rowsSELECT
a.`id` AS id,
a.`subject` AS NAME,
a.`price` AS curr,
@`a.price` AS pre,
@`a.price`:= a.price AS tmp
FROM table1 a,(SELECT @`a.price`:=0) s;
定义新的用户变量名(@`a.price`), initial value 等于 0。 当开始查询数据时,第i 行的数据暂时储存在(@`a.price`)中取名为tmp。当查询第i+1行时, pre等于查询第i 行的tmp。 构成了一个循环。 最终相邻两行的差值为curr - tmp。
Q2:查询每组中的前n条数据
#step 1:不分组加序号SELECT
(@`i` := @`i` + 1) rownum,
a.`id` AS id,
a.`order_type` AS type,
a.`price` AS curr
FROM general_order_trades a,(SELECT @`i` :=0) s;
#step2:分组,排序,加序号SELECT (@i := case when @pre_order_type = table1.order_type then @i + 1 else 1 end ) rownum,
table1.*,
(@pre_order_type := table1.order_type) as tmp
FROM
(SELECT order_type, subject, sum(price) as total_price
FROM general_order_trades #,GROUP BY order_type, subject
ORDER BY order_type,total_price) AS table1, (SELECT @i := 0, @pre_order_type:='') AS a;
我认为解决的这个问题的思路是对每组的每条数据编号(rownum)并形成一张新的表,根据rownum选出需要的前n行。
Step1: 加新的序号, 参考Q1中的用户变量
Step2: 先分组,命名新的表table1。 对于table1,判断第i行与第i+1行是否是同一个分组,如果是同一个分组rownum加1, 如果不是同一个分组rownum 等于1
Step3: 根据rownum选出每组的前n行。
Q3: 从给定的表中,随机查询几条数据
#querry 1:随机选取n条id连续数据SELECT *
FROM users AS t1
JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `users`)-(SELECT MIN(id) FROM users))+(SELECT MIN(id) FROM users)) AS userId) AS t2
WHERE t1.id >= t2.userId
ORDER BY t1.id
LIMIT 100;
#qerry2: 随机选取n条id不连续数据SELECT * FROM users
WHERE id >= ((SELECT MAX(id) FROM users)-(SELECT MIN(id) FROM users)) * RAND() + (SELECT MIN(id) FROM users)
ORDER BY id
LIMIT 1000
要回答这个问题,首先要考虑在 mysql中如何生成随机数,考虑函数RAND()生成0到1之间的随机数。
qerry1随机选取了n条id连续的数据。因为querry1是做了一个链接的操作(join), 表t1本身是按照id排序的,因此选取了n条id连续的数据。 而qerry2是把已经生成的随机数作为一个条件,因此选取了n条id不连续的数据。