想象一下,我有一张这样的表:
account_id date value
1 1/1/2015 5
1 1/3/2015 7
1 1/7/2015 8
3 1/2/2015 4
如果我想进行ORDER BY DATE和GROUP BY account_id并使用之前行的值更新每一行,该怎么办?
所以最终结果应该是:
account_id date value prev_value
1 1/1/2015 5 null
1 1/3/2015 7 5
1 1/7/2015 8 7
3 1/2/2015 4 null
在单个查询中执行此操作的任何好方法?
答案 0 :(得分:6)
lag(value anyelement [, offset integer [, default anyelement ]])
窗口功能会为您完成,基本上就是:
返回在 偏移 行之前评估的 值 分区中的当前行;如果没有这样的行,相反 return default(必须与value的类型相同)。两者都抵消了 并且相对于当前行评估默认值。如果省略, offset默认为1,默认为null
WITH t(account_id,date,value) AS ( VALUES
(1,'1/1/2015'::DATE,5),
(1,'1/3/2015'::DATE,7),
(1,'1/7/2015'::DATE,8),
(3,'1/2/2015'::DATE,4)
)
SELECT
*,
lag(value,1) OVER (PARTITION BY account_id) AS prev_value
FROM t
GROUP BY 1,2,3
ORDER BY 1,2,3;
结果:
account_id | date | value | prev_value
------------+----------+-------+------------
1 | 1/1/2015 | 5 |
1 | 1/3/2015 | 7 | 5
1 | 1/7/2015 | 8 | 7
3 | 1/2/2015 | 4 |
(4 rows)