使用Postgres中GROUP BY查询中上一行的值更新行

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)