Skip to content

[SQL] Implement session windows #6778

Description

@mihaibudiu

This is part of #659

Session window queries can be rewritten as standard SQL queries using LAG and comparing consecutive timestamps:

SELECT * FROM TABLE(
  SESSION(TABLE orders, DESCRIPTOR(rowtime), DESCRIPTOR(product), INTERVAL '20' MINUTE));

Equivalent form:

WITH
-- LAG finds each row's predecessor within its key
lagged AS (
  SELECT *,
         LAG(rowtime) OVER (PARTITION BY product ORDER BY rowtime) AS prev
  FROM orders          
  WHERE rowtime IS NOT NULL
),
-- brk = 1 when the row starts a new session
breaks AS (
  SELECT rowtime, id, product, units,
         CASE WHEN prev IS NULL
                OR rowtime >= prev + INTERVAL '20' MINUTE
              THEN 1 ELSE 0 END AS brk
  FROM lagged
),
-- the running sum of breaks numbers each row's session within its key
sessionized AS (
  SELECT rowtime, id, product, units,
         SUM(brk) OVER (PARTITION BY product ORDER BY rowtime
                        RANGE UNBOUNDED PRECEDING) AS sid
  FROM breaks
),
-- one row per session holding its bounds
bounds AS (
  SELECT product, sid, MIN(rowtime) AS min_ts, MAX(rowtime) AS max_ts
  FROM sessionized
  GROUP BY product, sid
)
-- attach the bounds back to every row of the session
SELECT s.rowtime, s.id, s.product, s.units,
       b.min_ts                        AS window_start,
       b.max_ts + INTERVAL '20' MINUTE AS window_end
FROM sessionized s
JOIN bounds b
  ON  s.product IS NOT DISTINCT FROM b.product
  AND s.sid     IS NOT DISTINCT FROM b.sid;

Metadata

Metadata

Assignees

Labels

SQL compilerRelated to the SQL compiler

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions