use*_*867 5 postgresql window-functions
想象一下,我有一张这样的桌子:
account_id date value
1 1/1/2015 5
1 1/3/2015 7
1 1/7/2015 8
3 1/2/2015 4
Run Code Online (Sandbox Code Playgroud)
如果我想执行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
Run Code Online (Sandbox Code Playgroud)
在单个查询中执行此操作的任何好方法?
Dmi*_*kov 10
lag(value anyelement [, offset integer [, default anyelement ]]) 窗口功能会为你做,基本上:
返回在分区内当前行之前的偏移行的行处计算的值 ; 如果没有这样的行,则返回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;
Run Code Online (Sandbox Code Playgroud)
结果:
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)
Run Code Online (Sandbox Code Playgroud)