Gaps, islands & sessionization
Concept  ·  SQL & Querying

Duration and events-per-session come from grouping by the derived session id.

The P14 staircase's last step: lag_gap_detect found the silences, session_running_flag minted the ids, and this atom cashes them — the derived id is a first-class grouping key, and every P04 skill applies at the new grain. Two edges: single-event sessions have duration 0 (real, and it feeds the denominator question); and session-level rollups per entity stack a second GROUP BY — avg_of_avgs waiting at the door.

See it break
pings
sidts
10
110
220
225
The trap
SELECT
  sid,
  COUNT(*) AS mins
FROM
  pings
GROUP BY
  sid
ORDER BY
  sid;
The fix
SELECT
  sid,
  MAX(ts) - MIN(ts) AS mins
FROM
  pings
GROUP BY
  sid
ORDER BY
  sid;
INPUTYour queryThe fix
1210
225

Session duration read as the event count (2, 2) instead of the elapsed span — once an id is minted, sessions are a grain, and duration is MAX(ts) - MIN(ts) per session (10 and 5), not the number of pings.

The rule

Metrics at session grain first; entity rollups as a deliberate second aggregation with stated weighting.

Shows up elsewhere
Sessionize by running-SUM of flagsAverage of averages
Try one →Prove it in practice →