使用Postgres

时间:2016-03-11 00:38:53

标签: 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

如果我想进行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

在单个查询中执行此操作的任何好方法?

1 个答案:

答案 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)