SQL Gaps and Islands

Finish the pattern from the previous lesson: GROUP BY that constant to turn scattered dates into clean streaks.

What & Why

"Islands" are the runs of consecutive dates; "gaps" are the breaks between them. Once each row has that grp value from the previous lesson, grouping by it collapses each island into a single summary row — start date, end date, streak length.

See How It Works

BUSINESS QUESTION

Collapse the observed growth-event dates into continuous calendar-day streaks.

iduser_idevent_namecreated_atproperties
1001101signup2024-01-15 09:12:00+00{"source":"organic"}
1002101activated2024-01-16 14:25:00+00{"step":"workspace"}
1003102signup2024-02-10 11:08:00+00{"source":"paid"}
1004103report_viewed2024-03-12 16:40:00+00{"report":"retention"}
Watch stable date keys collapse consecutive events into islandsStep 1 of 2
event_date - ROW_NUMBER()::int = island_key
event_daterow_numberisland_key
2024-01-1512024-01-14
2024-01-1622024-01-14
2024-02-1032024-02-07
2024-03-1242024-03-08

January 15 and 16 produce the same shifted key, so they belong to one island.

EXAMPLE QUERY
WITH event_days AS (
  SELECT DISTINCT created_at::date AS event_date
  FROM growth.events
),
numbered AS (
  SELECT
    event_date,
    event_date - ROW_NUMBER() OVER (ORDER BY event_date)::int AS island_key
  FROM event_days
)
SELECT
  MIN(event_date) AS streak_start,
  MAX(event_date) AS streak_end,
  COUNT(*) AS streak_days
FROM numbered
GROUP BY island_key
ORDER BY streak_start;

This lesson's practice is part of Pro.

Advanced business practice

Sign up free to try it on a real business scenario