sqlpostgresqlwindowing

How do I window Postgre SQL rows based on row data?


I have a table that has a timestamp column and some data columns. Given a interval length T (say 30minutes) I want to partition the table into 'sessions'. Two adjacent rows (when sorted by the timestamp) are in the same 'session' if the difference of the timestamp values is less than T. If the difference is more than T then there is a break in sessions. For example, the table below has two gaps of more than T that split the sessions. How do I generate the session column with SQL?

row timestamp session
1 18:00 1
2 18:02 1
3 18:04 1
4 18:30 1
5 19:10 2
6 19:20 2
7 20:20 3

Solution

  • You can use lag() on the timestamp to measure the difference and then a cumulative sum to calculate the session:

    select t.*,
           sum(case when prev_timestamp > timetamp - interval '30 minute' then 0 else 1 end) over
               (order by timestamp) as session
    from (select t.*,
                 lag(timestamp) over (order by timestamp) as prev_timestamp
          from t
         ) t;
    

    Or, you could use count() with filter in Postgres:

    select t.*,
           1 + count(*) filter (where prev_timestamp < timestamp - interval '30 minute') over (order by timestamp) as session
    from (select t.*,
                 lag(timestamp) over (order by timestamp) as prev_timestamp
          from t
         ) t;