Date Gaps or Continuous Date Ranges

Something I’ve encountered in multiple interviews is the need to identify gaps between dates or continuous date ranges. In the moment, it can be tough to recall all the approaches, so I’m documenting these queries here as a reference for the future.

Finding Consecutive Date Ranges

WITH
numbered AS
(
SELECT
ad_id,
eventdate,
DENSE_RANK() OVER (PARTITION BY ad_id ORDER BY eventdate) AS rn
FROM
facebook_spend_data
WHERE
ad_id = '6245581352190'
GROUP BY
ad_id, eventdate
),
date_groups AS
(
SELECT
ad_id,
eventdate,
rn,
DATEADD(day, -rn, eventdate) AS grp_date
FROM
numbered
)
SELECT
ad_id,
MIN(eventdate) interval_start,
MAX(eventdate) interval_end,
1 + MAX(eventdate) - MIN(eventdate) AS consecutive_days
FROM date_groups
GROUP BY ad_id, grp_date
ORDER BY ad_id, interval_start;
  • We use dense_rank to identify the order when the event happened.
AD_IDEVENTDATERN
62455813521902021-10-251
62455813521902021-10-262
62455813521902021-10-273
62455813521902021-10-284
62455813521902021-10-295
62455813521902021-11-036
  • We subtract the rank minus the date when the event happened, and this will give us the initial date of the range
AD_IDEVENTDATERNGRP_DATE
62455813521902021-10-2512021-10-24
62455813521902021-10-2622021-10-24
62455813521902021-10-2732021-10-24
62455813521902021-10-2842021-10-24
62455813521902021-10-2952021-10-24
62455813521902021-11-0362021-10-28
  • We grouped by grp_date, and get the max and min date, and then subtracts max and min to get the number of consecutive days
AD_IDINTERVAL_STARTINTERVAL_ENDCONSECUTIVE_DAYS
62455813521902021-10-252021-10-295
62455813521902021-11-032021-11-031

Finding gaps between days

WITH
previous_days AS
(
SELECT
ad_id,
eventdate,
LAG(eventdate) OVER (partition by ad_id ORDER BY eventdate) previous_date
FROM
facebook_spend_data
WHERE
ad_id = '6245581352190'
GROUP BY
ad_id, eventdate
)
SELECT
ad_id,
eventdate,
previous_date,
DATEDIFF(day, previous_date, eventdate)
FROM
previous_days;
  • Using LAG, we can get the previous date
AD_IDEVENTDATEPREVIOUS_DATE
62455813521902021-10-25
62455813521902021-10-262021-10-25
62455813521902021-10-272021-10-26
62455813521902021-10-282021-10-27
62455813521902021-10-292021-10-28
62455813521902021-11-032021-10-29
  • We can use DATEDIFF to subtract the dates
AD_IDEVENTDATEPREVIOUS_DATEGAP_BETWEEN_DAYS
62455813521902021-10-25
62455813521902021-10-262021-10-251
62455813521902021-10-272021-10-261
62455813521902021-10-282021-10-271
62455813521902021-10-292021-10-281
62455813521902021-11-032021-10-295