简体   繁体   中英

Select previous different value PostgreSQL

I have a table:

id date value
1 2022-01-01 1
1 2022-01-02 1
1 2022-01-03 2
1 2022-01-04 2
1 2022-01-05 3
1 2022-01-06 3

I want to detect changing of value column by date:

id date value diff
1 2022-01-01 1 null
1 2022-01-02 1 null
1 2022-01-03 2 1
1 2022-01-04 2 1
1 2022-01-05 3 2
1 2022-01-06 3 2

I tried a window function lag(), but all I got:

id date value diff
1 2022-01-01 1 null
1 2022-01-02 1 1
1 2022-01-03 2 1
1 2022-01-04 2 2
1 2022-01-05 3 2
1 2022-01-06 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;

db<>fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM