Question presented to candidate:
"Two related problems. First, our invoice numbers should be continuous, so find every missing range. Second, from the logins table, find each user's streaks of consecutive login days, with start date, end date and length. How do you approach these gaps-and-islands problems in SQL?"
What a strong answer should cover:
- The vocabulary: an island is a maximal run of consecutive values (or consecutive rows with the same state), a gap is the space between islands
- Gaps:
LEAD(x) OVER (ORDER BY x)puts the next value on each row; wherenext - x > 1there is a gap fromx + 1tonext - 1 - Islands, method 1 (difference of sequences):
value - ROW_NUMBER()is constant inside a run of consecutive values, so it works as a group key forGROUP BY - Islands, method 2 (change flag + running sum):
LAGmarks rows where the state changes, a runningSUMof the flags numbers the runs; works for "same status" runs where values are not numbers - Pitfalls: duplicates break the ROW_NUMBER trick (de-duplicate first or use
DENSE_RANK),PARTITION BYper entity, and the date arithmetic differs per engine
Clarifying questions expected:
- Can the same value appear twice (two logins on one day), and does it count once?
- What counts as "consecutive": calendar days, business days, or a tolerance such as "within 30 minutes"?
- Is the expected output one row per island, or each row tagged with its island?
Code / implementation expected: Yes โ a LEAD-based gap query and at least one island-grouping query with the ROW_NUMBER difference or the running-sum technique.
Schema used by the examples: