【发布时间】:2020-03-06 23:43:38
【问题描述】:
以这张表为例:
+----+------------+------+
| id | date | flag |
+----+------------+------+
| A | 01/01/2020 | 0 |
| A | 01/02/2020 | 0 |
| A | 01/03/2020 | 0 |
| A | 01/04/2020 | 1 |
| A | 01/05/2020 | 1 |
| B | 01/01/2020 | 0 |
| B | 01/02/2020 | 1 |
| B | 01/03/2020 | 1 |
| B | 01/04/2020 | 1 |
| B | 01/05/2020 | 1 |
+----+------------+------+
有一些标志设置为 0 或 1。我想创建一个名为 day_flagged 的新列,其中将包含标志首次变为 1 的日期。例如,对于 id A,即将是01/04/2020。对于id B,那就是01/02/2020。
这是我目前拥有的:
SELECT x.id,
x.date,
( CASE
WHEN prev_flag = 0
AND next_flag = 1
AND x.flag = 1 THEN 1
ELSE NULL
END ) AS flagged
FROM (SELECT id,
date,
flag,
Lag(flag)
OVER (
partition BY id
ORDER BY date ASC) AS prev_flag,
Lead(flag)
OVER (
partition BY id
ORDER BY date ASC) AS next_flag
FROM tableA) AS x;
结果是这样的:
+----+------------+---------+
| id | date | flagged |
+----+------------+---------+
| A | 01/01/2020 | null |
| A | 01/02/2020 | null |
| A | 01/03/2020 | null |
| A | 01/04/2020 | 1 |
| A | 01/05/2020 | null |
| B | 01/01/2020 | null |
| B | 01/02/2020 | 1 |
| B | 01/03/2020 | null |
| B | 01/04/2020 | null |
| B | 01/05/2020 | null |
+----+------------+---------+
我能够确定每个 id 的 flag 的值何时从 0 首次变为 1,并将其存储在 flagged 中。如何获取与flagged 为1 的行对应的date 值,并将该日期作为day_flagged 插入分区的每一行?
期望的结果:
+----+------------+------+-------------+
| id | date | flag | day_flagged |
+----+------------+------+-------------+
| A | 01/01/2020 | 0 | 01/04/2020 |
| A | 01/02/2020 | 0 | 01/04/2020 |
| A | 01/03/2020 | 0 | 01/04/2020 |
| A | 01/04/2020 | 1 | 01/04/2020 |
| A | 01/05/2020 | 1 | 01/04/2020 |
| B | 01/01/2020 | 0 | 01/02/2020 |
| B | 01/02/2020 | 1 | 01/02/2020 |
| B | 01/03/2020 | 1 | 01/02/2020 |
| B | 01/04/2020 | 1 | 01/02/2020 |
| B | 01/05/2020 | 1 | 01/02/2020 |
+----+------------+------+-------------+
【问题讨论】:
标签: sql postgresql window-functions postgresql-9.6