如何在MySQL中滞后列?

时间:2011-03-30 07:37:37

标签: mysql sql data-analysis sliding-window

考虑下表:

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

id列自动递增但包含间隙。 value列是数字。

我希望通过将valuevalue两行相关联来设置value随时间的增长。这是针对行id=85我要设置行value的{​​{1}}(546)与行id=85的{​​{1}}(334)相关。因此,行value的计算值为546/334 = 1.63473。

这是我想要达到的结果:

id=27

如何在MySQL中执行这样的滞后?

请注意,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) +-----+---------+---------------------+ 加入同一个表格即可。

2 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:0)

由于当前的一行与您想要获取“历史”数据的行之间只有两行,因此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;

这是一个非常不整洁的解决方案,但我认为它会完成这项工作。也许有一些方法可以阻止变量的显示,我还没有考虑到这一点。