Field note · February 3, 2025

Finding the gaps in support-tickets

gaps and islands against a real schema, and the clause in it that is doing the work.

1 min read ·Analytics engineering ·sql

Finding the gaps in support-tickets comes up often enough to be worth a note. support-tickets is a convenient thing to try it on — 4,000 rows, one row per ticket.

sql
with numbered as (
  select channel, opened_at,
         row_number() over (partition by channel order by opened_at) as rn
  from support_tickets
)
select channel,
       min(opened_at) as island_start,
       max(opened_at) as island_end,
       count(*)   as readings
from (
  select *, date_trunc('day', opened_at) - (rn * interval '1 day') as grp_key
  from numbered
) t
group by channel, grp_key
order by channel, island_start;

The trick is that subtracting a dense row number from a dense date gives a constant inside a run and a different constant across a gap. Once you have seen it the query is obvious; before that it looks like a magic trick.

Run it against the real file in the SQL playground — the engine there is enough of a SQL implementation to execute this as written, and the dataset is already loaded. The pattern page has the version with the failure modes spelled out.

Window functions are the difference between SQL that describes rows and SQL that describes sequences. Almost every "we exported it to pandas to do this bit" turns out to be one of these five.

AE

Analytics engineering

Turning warehouses full of raw tables into models an analyst can trust without asking anyone.

Dimensional modelling, grain, slowly changing dimensions, metric definitions, and the SQL that survives production. Most "we need a data scientist" problems are "we need one correct table" problems.

Related

All field notes    2025 archive