繁体   English   中英

如何在MySQL中滞后列?

[英]How do I lag columns in 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我想设置的valueid=85的关系(546)的value列的id=27 (334)。 因此,行id=85计算值为546/334 = 1.63473。

这是我想要实现的结果:

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 ,因此只需使用t1.id = t2.id - 2连接到同一个表就不起作用了。

这是一个在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;

由于当前只有两行和您想要获取“历史”数据的行,因此perphaps可以使用变量临时存储数据,例如:

set @oldid0=999999;
set @oldid1=999999;
set @oldid2=999999;
select @oldid0:=@oldid1,@oldid1:=@oldid2,@oldid2:=id, value/@oldid0 from table order by id asc;

这是一个非常不整洁的解决方案,但我认为它将完成这项工作。 也许有一些方法可以防止显示变量,我没有那么深入地研究它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM