AdvancedWindow Functions

Sessionization: group events by session

The query

SQL
SELECT
  user_id,
  event_time,
  event_type,
  SUM(is_new_session) OVER (PARTITION BY user_id ORDER BY event_time) AS session_id
FROM (
  SELECT
    user_id,
    event_time,
    event_type,
    CASE WHEN event_time - LAG(event_time) OVER (
      PARTITION BY user_id ORDER BY event_time
    ) > INTERVAL '30 minutes'
    OR LAG(event_time) OVER (PARTITION BY user_id ORDER BY event_time) IS NULL
    THEN 1 ELSE 0 END AS is_new_session
  FROM user_events
) flagged
ORDER BY user_id, event_time;
Tested against PostgreSQL 16

Note

Sessionization: new session if gap > 30min. Running SUM of session flags = session number.