-- Session Analysis -- split each user's event stream into sessions based on -- inactivity gap, then aggregate per session. -- -- Required parameters (clickhouse.Named): -- workspace_id : String -- from : DateTime64(3,'UTC') -- to : DateTime64(3,'UTC') -- timeout_seconds : UInt32 -- limit : UInt32 -- offset : UInt32 -- -- Optional parameters (template-driven): -- user_id : String (when .HasUserID) SELECT user_id, session_index AS session_id, min(timestamp) AS started_at, max(timestamp) AS ended_at, count() AS events, dateDiff('second', min(timestamp), max(timestamp)) AS duration_seconds FROM ( SELECT user_id, timestamp, sum(is_new_session) OVER (PARTITION BY user_id ORDER BY timestamp) AS session_index FROM ( SELECT user_id, timestamp, if( dateDiff( 'second', lagInFrame(timestamp) OVER (PARTITION BY user_id ORDER BY timestamp), timestamp ) > {timeout_seconds:UInt32}, 1, 0 ) AS is_new_session FROM events_track WHERE workspace_id = {workspace_id:String} AND received_at >= {from:DateTime64(3,'UTC')} AND received_at < {to:DateTime64(3,'UTC')} AND user_id != '' {{- if .HasUserID }} AND user_id = {user_id:String} {{- end }} ) ) GROUP BY user_id, session_index ORDER BY started_at DESC LIMIT {limit:UInt32} OFFSET {offset:UInt32}