简体   繁体   English

如何在MySQL中滞后列?

[英]How do I lag columns in MySQL?

Consider the following table: 请考虑下表:

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

The id column is auto-incremented but contains gaps. id列自动递增但包含间隙。 The value column is numeric. value列为数字。

I want to look at the increase in value over time by setting value in relation to the value two rows above. 我想看看在增加value通过设置随时间的value相对于value上面两行。 That is for row id=85 I want to set the value of row id=85 (546) in relation to the value of row id=27 (334). 这是行id=85我想设置的valueid=85的关系(546)的value列的id=27 (334)。 The value to be computed for row id=85 is hence 546/334=1.63473. 因此,行id=85计算值为546/334 = 1.63473。

This is the result I want to achieve: 这是我想要实现的结果:

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)
+-----+---------+---------------------+

How do I perform such lagging in MySQL? 我如何在MySQL中执行这样的滞后?

Please note that the id column contains gaps, so simply joining on the same table with t1.id = t2.id - 2 will not work. 请注意, id列包含t1.id = t2.id - 2 ,因此只需使用t1.id = t2.id - 2连接到同一个表就不起作用了。

Here is a solution that returns what you want in MySQL 这是一个在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 doesn't like a self join against a subquery so you have to count rows twice, so not as tidy or scalable as it might be, but it does make specifying the lag simple. MySQL 5.1不喜欢针对子查询的自连接,因此你必须计算两次行,所以不要像它可能那样整洁或可扩展,但它确实使得指定滞后变得简单。

For readers that use Oracle instead this is much easier 对于使用Oracle的读者而言,这更容易

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

As there are only two rows between the current one and the one from where you want to get the 'historical' data could you perphaps use variables to store the data temporarily using something like: 由于当前只有两行和您想要获取“历史”数据的行,因此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;

It is a very untidy solution but I think it will do the job. 这是一个非常不整洁的解决方案,但我认为它将完成这项工作。 Maybe there is some way of preventing the variables from being displayed, I've not looked into it that far. 也许有一些方法可以防止显示变量,我没有那么深入地研究它。

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

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