[英]Select previous different value PostgreSQL
I have a table:我有一张桌子:
id ID | date日期 | value价值 |
---|---|---|
1 1 | 2022-01-01 2022-01-01 | 1 1 |
1 1 | 2022-01-02 2022-01-02 | 1 1 |
1 1 | 2022-01-03 2022-01-03 | 2 2 |
1 1 | 2022-01-04 2022-01-04 | 2 2 |
1 1 | 2022-01-05 2022-01-05 | 3 3 |
1 1 | 2022-01-06 2022-01-06 | 3 3 |
I want to detect changing of value column by date:我想按日期检测值列的变化:
id ID | date日期 | value价值 | diff差异 |
---|---|---|---|
1 1 | 2022-01-01 2022-01-01 | 1 1 | null无效的 |
1 1 | 2022-01-02 2022-01-02 | 1 1 | null无效的 |
1 1 | 2022-01-03 2022-01-03 | 2 2 | 1 1 |
1 1 | 2022-01-04 2022-01-04 | 2 2 | 1 1 |
1 1 | 2022-01-05 2022-01-05 | 3 3 | 2 2 |
1 1 | 2022-01-06 2022-01-06 | 3 3 | 2 2 |
I tried a window function lag(), but all I got:我尝试了一个窗口函数 lag(),但我得到的只是:
id ID | date日期 | value价值 | diff差异 |
---|---|---|---|
1 1 | 2022-01-01 2022-01-01 | 1 1 | null无效的 |
1 1 | 2022-01-02 2022-01-02 | 1 1 | 1 1 |
1 1 | 2022-01-03 2022-01-03 | 2 2 | 1 1 |
1 1 | 2022-01-04 2022-01-04 | 2 2 | 2 2 |
1 1 | 2022-01-05 2022-01-05 | 3 3 | 2 2 |
1 1 | 2022-01-06 2022-01-06 | 3 3 | 3 3 |
I am pretty sure you have to do a gaps-and-islands to "group" your changes.我很确定你必须做一个间隙和岛屿来“分组”你的更改。
There may be a more concise way to get the result you want, but this is how I would solve this:可能有一种更简洁的方法来获得您想要的结果,但这就是我将如何解决这个问题:
with changes as ( -- mark the changes and lag values
select id, date, value,
coalesce((value != lag(value) over w)::int, 1) as changed_flag,
lag(value) over w as last_value
from a_table
window w as (partition by id order by date)
), groupnums as ( -- number the groups, carrying the lag values forward
select id, date, value,
sum(changed_flag) over (partition by id order by date) as group_num,
last_value
from changes
window w as (partition by id order by date)
) -- final query that uses group numbering to return the correct lag value
select id, date, value,
first_value(last_value) over (partition by id, group_num
order by date) as diff
from groupnums;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.