一尘不染

如何滞后MySQL中的列?

mysql

请考虑下表:

SELECT id, value FROM table ORDER BY id ASC;
+-----+---------+
| id  | value   |
+-----+---------+
| 12  | 158     |
| 15  | 346     |
| 27  | 334     |
| 84  | 378     |
| 85  | 546     |
+-----+---------+

id列会自动增加,但包含空白。该value列为数字。

我想value通过设置value相对于上述value两行的方式来查看随时间的增长。那是针对行,id=85我要相对于行(334)设置valueid=85(546
)的。因此,要为行计算的值是546/334 = 1.63473。value``id=27``id=85

这是我想要实现的结果:

SELECT id, value, ...;
+-----+---------+---------------------+
| id  | value   | value/lag(value, 2) | (the syntax value/lag(value, 2) is made up)
+-----+---------+---------------------+
| 12  | 158     | NULL                |
| 15  | 346     | NULL                |
| 27  | 334     | 2.11392             | (334/158=2.11392)
| 84  | 378     | 1.09248             | (378/346=1.09248)
| 85  | 546     | 1.63473             | (546/334=1.63473)
+-----+---------+---------------------+

如何在MySQL中执行此类滞后?

请注意,该id列包含空格,因此仅在与同一表上的连接t1.id = t2.id - 2将不起作用。


阅读 227

收藏
2020-05-17

共1个答案

一尘不染

这是一个返回MySQL所需内容的解决方案

SET @a :=0;
SET @b :=2;
SELECT r.id, r.value, r.value/r2.value AS 'lag'
FROM
(SELECT if(@a, @a:=@a+1, @a:=1) as rownum, id, value FROM results) AS r
LEFT JOIN
(SELECT if(@b, @b:=@b+1, @b:=1) as rownum, id, value FROM results) AS r2
ON r.rownum = r2.rownum

MySQL 5.1不喜欢针对子查询的自联接,因此您必须对行进行两次计数,因此可能不够整洁或可扩展,但是它确实使指定滞后变得简单。

对于使用Oracle的读者来说,这要容易得多

SELECT id, value, value/lag(value, 2) over (order by id) as lag from results;
2020-05-17