【发布时间】:2018-09-05 15:26:59
【问题描述】:
我有一个如下所示的 postgres 表:
refnum | period | flag
--------+--------+------
ref01 | 201701 | 0
ref01 | 201702 | 0
ref01 | 201703 | 1
ref01 | 201704 | 0
ref01 | 201705 | 0
ref01 | 201706 | 1
ref01 | 201707 | 0
其中 period 基本上只是一个 int 形式的年月时间戳。我想这样做,以便我们添加一个列来维护标志 = 1 的最后一个时期。所以它应该在最后看起来像这样:
refnum | period | flag | lastPeriod
--------+--------+------+------------
ref01 | 201701 | 0 | NULL
ref01 | 201702 | 0 | NULL
ref01 | 201703 | 1 | 201703
ref01 | 201704 | 0 | 201703
ref01 | 201705 | 0 | 201703
ref01 | 201706 | 1 | 201706
ref01 | 201707 | 0 | 201706
因此,每一行的 lastPeriod 列都取决于前一行中该列的具体化值。我尝试使用窗口函数和 LAG 来执行此操作,但这仅在您知道要回顾的行数时才有效。如果窗口中的每一行都在前一行之后进行评估,那就太好了,但似乎它们是独立于之前的值运行的。我基本上想要的是类似的东西:
SELECT CASE WHEN current_row.flag = 1 THEN current_row.period ELSE prev_row.lastPeriod
我想出了解决这个问题的一种方法,但它基本上涉及创建一个临时表,其中包含标志 = 1 的所有时段,加入该表,然后拉取最大值:
select refnum, period, max(backfill) FROM
(
select refnum, a.period as period, b.period as backfill
FROM my_table a
LEFT JOIN tmp_periods b ON a.period >= b.period
) as foo group by refnum, period order by period;
但我希望我们能以更好的方式做到这一点,因为我们正在查看的表格非常大。
【问题讨论】:
标签: sql postgresql window-functions