Sql 生成包含下一行值的日期序列
我有一张桌子:Sql 生成包含下一行值的日期序列,sql,postgresql,date,group-by,gaps-and-islands,Sql,Postgresql,Date,Group By,Gaps And Islands,我有一张桌子: ╔════════════╦════════╦════════════╗ ║ product_id ║ amount ║ date ║ ╠════════════╬════════╬════════════╣ ║ 1 ║ 100 ║ 2019-01-01 ║ ║ 2 ║ 150 ║ 2019-01-01 ║ ║ 1 ║ 200 ║ 2019-01-05 ║ ║ 2
╔════════════╦════════╦════════════╗
║ product_id ║ amount ║ date ║
╠════════════╬════════╬════════════╣
║ 1 ║ 100 ║ 2019-01-01 ║
║ 2 ║ 150 ║ 2019-01-01 ║
║ 1 ║ 200 ║ 2019-01-05 ║
║ 2 ║ 180 ║ 2019-01-03 ║
║ 2 ║ 150 ║ 2019-01-05 ║
╚════════════╩════════╩════════════╝
我需要根据下一行值(金额)生成产品行。我需要这样的结果:
╔════════════╦════════╦════════════╗
║ product_id ║ amount ║ date ║
╠════════════╬════════╬════════════╣
║ 1 ║ 100 ║ 2019-01-01 ║
║ 1 ║ 100 ║ 2019-01-02 ║
║ 1 ║ 100 ║ 2019-01-03 ║
║ 1 ║ 100 ║ 2019-01-04 ║
║ 1 ║ 200 ║ 2019-01-05 ║
║ 2 ║ 150 ║ 2019-01-01 ║
║ 2 ║ 150 ║ 2019-01-02 ║
║ 2 ║ 180 ║ 2019-01-03 ║
║ 2 ║ 180 ║ 2019-01-04 ║
║ 2 ║ 150 ║ 2019-01-05 ║
╚════════════╩════════╩════════════╝
您可以在聚合子查询中使用
generate_series()
来生成“缺失”日期
然后,我们需要在新行上引入前面的非空值-如果Postgres支持ignore nulls
选项到lag()
,这将是直接的-但是它不支持。解决此问题的一种方法是使用窗口计数来定义组,然后首先使用value():
:
product_id | dt | amount
---------: | :--------------------- | -----:
1 | 2019-01-01 00:00:00+00 | 100
1 | 2019-01-02 00:00:00+00 | 100
1 | 2019-01-03 00:00:00+00 | 100
1 | 2019-01-04 00:00:00+00 | 100
1 | 2019-01-05 00:00:00+00 | 200
2 | 2019-01-01 00:00:00+00 | 150
2 | 2019-01-02 00:00:00+00 | 150
2 | 2019-01-03 00:00:00+00 | 180
2 | 2019-01-04 00:00:00+00 | 180
2 | 2019-01-05 00:00:00+00 | 150
产品id | dt |金额
---------: | :--------------------- | -----:
1 | 2019-01-01 00:00:00+00 | 100
1 | 2019-01-02 00:00:00+00 | 100
1 | 2019-01-03 00:00:00+00 | 100
1 | 2019-01-04 00:00:00+00 | 100
1 | 2019-01-05 00:00:00+00 | 200
2 | 2019-01-01 00:00:00+00 | 150
2 | 2019-01-02 00:00:00+00 | 150
2 | 2019-01-03 00:00:00+00 | 180
2 | 2019-01-04 00:00:00+00 | 180
2 | 2019-01-05 00:00:00+00 | 150
product_id | dt | amount
---------: | :--------------------- | -----:
1 | 2019-01-01 00:00:00+00 | 100
1 | 2019-01-02 00:00:00+00 | 100
1 | 2019-01-03 00:00:00+00 | 100
1 | 2019-01-04 00:00:00+00 | 100
1 | 2019-01-05 00:00:00+00 | 200
2 | 2019-01-01 00:00:00+00 | 150
2 | 2019-01-02 00:00:00+00 | 150
2 | 2019-01-03 00:00:00+00 | 180
2 | 2019-01-04 00:00:00+00 | 180
2 | 2019-01-05 00:00:00+00 | 150