ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Detect Gaps in Sequential IDs

SQL

Goal -- WPM

Ready
Exercise Algorithm Area
1WITH RankedIDs AS (
2SELECT
3ID,
4ROW_NUMBER() OVER (ORDER BY ID) as rn
5FROM
6YourTable
7WHERE
8ID IS NOT NULL
9)
10SELECT
11ri.ID + 1 AS MissingIDStart,
12next_ri.ID - 1 AS MissingIDEnd
13FROM
14RankedIDs ri
15JOIN
16RankedIDs next_ri ON ri.rn + 1 = next_ri.rn
17WHERE
18ri.ID + 1 < next_ri.ID;
19
20-- Alternative using LAG() window function
21WITH LaggedIDs AS (
22SELECT
23ID,
24LAG(ID, 1) OVER (ORDER BY ID) as PrevID
25FROM
26YourTable
27WHERE
28ID IS NOT NULL
29)
30SELECT
31PrevID + 1 AS MissingIDStart,
32ID - 1 AS MissingIDEnd
33FROM
34LaggedIDs
35WHERE
36PrevID IS NOT NULL AND ID > PrevID + 1;
37
38-- Helper function concept: is_gap
39-- This is determined by checking if the current ID is greater than the previous ID + 1.
40
41-- Edge case: Empty YourTable
42-- Both approaches will return an empty result set, which is correct.
43
44-- Edge case: YourTable with only one record
45-- The JOIN in the first approach will not find a match for ri.rn + 1 = next_ri.rn.
46-- The LAG() approach will have PrevID as NULL for the single row, so the WHERE clause will filter it out.
47-- Both correctly return no gaps.
48
49-- Edge case: NULL IDs
50-- Rows with NULL IDs are filtered out by the WHERE clause.
51
52-- Invariant: The returned rows represent ranges of missing sequential IDs between existing IDs in the table.
53
54-- Correctness argument:
55-- The first approach ranks all existing IDs sequentially. It then joins the ranked IDs to find adjacent pairs (rn and rn+1). If the ID of the current rank (ri.ID) plus one is less than the ID of the next rank (next_ri.ID), it signifies a gap. The gap starts at ri.ID + 1 and ends at next_ri.ID - 1.
56-- The second approach uses LAG() to get the previous ID. It then checks if the current ID is more than one greater than the previous ID. If so, a gap exists from PrevID + 1 to ID - 1. Both methods accurately identify and report these gaps.
Algorithm description viewbox

Detect Gaps in Sequential IDs

Algorithm description:

This SQL query detects gaps in a sequence of numerical IDs, such as order IDs or primary keys. Identifying missing IDs is crucial for data integrity checks, ensuring no records have been lost or skipped, and for understanding the completeness of sequential data. The query uses window functions to compare adjacent IDs and pinpoint where the sequence breaks.

Algorithm explanation:

The algorithm identifies gaps in a sequence of IDs. It first ranks all existing IDs sequentially using `ROW_NUMBER()` ordered by the ID itself. In the first method, it then joins this ranked list to itself, matching consecutive ranks (`ri.rn + 1 = next_ri.rn`). If the current ID (`ri.ID`) plus one is less than the next ID (`next_ri.ID`), a gap is detected. The gap spans from `ri.ID + 1` to `next_ri.ID - 1`. The second method uses the `LAG()` window function to retrieve the previous ID for each row. It then filters for rows where the current ID is greater than the previous ID plus one, indicating a gap from `PrevID + 1` to `ID - 1`. Both methods handle empty tables and single-record tables correctly by returning no gaps. Time complexity is typically O(N log N) due to sorting for ranking/lagging, where N is the number of records. Space complexity is O(N) for intermediate CTEs.

Pseudocode:

1. Get all existing IDs from the table.
2. Sort these IDs in ascending order.
3. For each ID, find the immediately preceding ID.
4. If the current ID is greater than the preceding ID plus 1, then there is a gap.
5. The gap starts at the preceding ID plus 1 and ends at the current ID minus 1.
6. Report these gaps.