Bird
Raised Fist0
SQLquery~10 mins

Finding gaps in sequences in SQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Finding gaps in sequences
Start with ordered sequence
↓
Compare each value with previous
↓
Check if difference > 1
↓
Record gap
↓
End of sequence
We look at each number in order and compare it to the one before. If the difference is more than 1, we found a gap.
Execution Sample
SQL
WITH ordered AS (
  SELECT id, value, LAG(value) OVER (ORDER BY value) AS prev_value
  FROM numbers
)
SELECT prev_value + 1 AS gap_start, value - 1 AS gap_end
FROM ordered
WHERE value - prev_value > 1;
This SQL finds gaps in a sequence of numbers by comparing each number to the previous one.
Execution Table
Stepidvalueprev_valuevalue - prev_valueGap Found?Output (gap_start, gap_end)
111NULLNULLNoNULL
22211NoNULL
33422Yes(3, 3)
44541NoNULL
55752Yes(6, 6)
66871NoNULL
771082Yes(9, 9)
8EndNULLNULLNULLStopNo more rows
💡 Reached end of sequence, no more rows to compare.
Variable Tracker
VariableStartAfter 1After 2After 3After 4After 5After 6After 7Final
valueNULL12457810NULL
prev_valueNULLNULL124578NULL
value - prev_valueNULLNULL121212NULL
Gap Found?NoNoNoYesNoYesNoYesNo more rows
Key Moments - 3 Insights
Why is prev_value NULL on the first row?
Because there is no previous row for the first value, LAG returns NULL as shown in execution_table step 1.
Why do we check if value - prev_value > 1 to find gaps?
If the difference is more than 1, it means numbers are missing between prev_value and value, as seen in steps 3, 5, and 7.
What does the output (gap_start, gap_end) represent?
It shows the start and end of the missing numbers between two existing values, calculated as prev_value + 1 and value - 1.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of prev_value at step 4?
A2
B4
CNULL
D5
💡 Hint
Check the 'prev_value' column in execution_table row for step 4.
At which step does the first gap get detected?
AStep 2
BStep 4
CStep 3
DStep 5
💡 Hint
Look for the first 'Yes' in the 'Gap Found?' column in execution_table.
If the sequence had no missing numbers, what would the 'Gap Found?' column show?
AAll No
BAll Yes
CAlternating Yes and No
DNULL values
💡 Hint
Refer to the condition 'value - prev_value > 1' in execution_table; if no gaps, difference is always 1.
Concept Snapshot
Finding gaps in sequences:
- Use LAG() to get previous value in order
- Compare current and previous values
- If difference > 1, gap exists
- Output missing ranges as prev_value+1 to value-1
- Works well for ordered numeric sequences
Full Transcript
This visual execution shows how to find gaps in a sequence of numbers using SQL. We start by ordering the numbers and using the LAG function to get the previous number for each row. Then we calculate the difference between the current and previous values. If this difference is greater than one, it means there is a gap. We record the start and end of the gap by adding one to the previous value and subtracting one from the current value. The execution table traces each step, showing when gaps are found and what output is produced. Key moments clarify why the first previous value is NULL and how the gap detection works. The quiz tests understanding of these steps by referencing the execution table and variable changes.

Practice

(1/5)
1. What is the main purpose of using the LEAD() function when finding gaps in a sequence of numbers in SQL?
easy
A. To find the maximum number in the sequence
B. To compare each number with the next number in the sequence
C. To sum all numbers in the sequence
D. To sort the numbers in descending order

Solution

  1. Step 1: Understand the role of LEAD()

    The LEAD() function allows you to look at the next row's value in the current row's context.
  2. Step 2: Identify how LEAD() helps find gaps

    By comparing the current number with the next number, you can detect if there is a gap (difference greater than 1).
  3. Final Answer:

    To compare each number with the next number in the sequence -> Option B
  4. Quick Check:

    LEAD() compares current and next values [OK]
Hint: Use LEAD() to peek at the next number in sequence [OK]
Common Mistakes:
  • Thinking LEAD() sums values
  • Confusing LEAD() with aggregate functions
  • Using LEAD() to sort data
2. Which of the following SQL snippets correctly uses LEAD() to find gaps in a sequence column named num in table numbers?
easy
A. SELECT num, LEAD(num) AS next_num FROM numbers;
B. SELECT num, LEAD(num) FROM numbers ORDER BY num;
C. SELECT num, LEAD(num) OVER (ORDER BY num) AS next_num FROM numbers;
D. SELECT num, LEAD(num) OVER () AS next_num FROM numbers;

Solution

  1. Step 1: Check LEAD() syntax

    The correct syntax requires LEAD(column) OVER (ORDER BY column) to define the order for the window function.
  2. Step 2: Identify the correct option

    SELECT num, LEAD(num) OVER (ORDER BY num) AS next_num FROM numbers; uses LEAD(num) OVER (ORDER BY num), which is the correct form to get the next number in order.
  3. Final Answer:

    SELECT num, LEAD(num) OVER (ORDER BY num) AS next_num FROM numbers; -> Option C
  4. Quick Check:

    LEAD() needs OVER with ORDER BY [OK]
Hint: Always include OVER(ORDER BY column) with LEAD() [OK]
Common Mistakes:
  • Omitting OVER clause
  • Not specifying ORDER BY inside OVER
  • Using LEAD() without alias
3. Given the table numbers with column num containing values (1, 2, 4, 5, 7), what will the following query return?
SELECT num, LEAD(num) OVER (ORDER BY num) AS next_num FROM numbers;
medium
A. [{num:1, next_num:2}, {num:2, next_num:4}, {num:4, next_num:5}, {num:5, next_num:7}, {num:7, next_num:null}]
B. [{num:1, next_num:1}, {num:2, next_num:2}, {num:4, next_num:4}, {num:5, next_num:5}, {num:7, next_num:7}]
C. [{num:1, next_num:3}, {num:2, next_num:4}, {num:4, next_num:6}, {num:5, next_num:7}, {num:7, next_num:null}]
D. [{num:1, next_num:null}, {num:2, next_num:null}, {num:4, next_num:null}, {num:5, next_num:null}, {num:7, next_num:null}]

Solution

  1. Step 1: Understand LEAD() output

    LEAD(num) returns the next row's num value ordered by num. So each row shows its own num and the next number.
  2. Step 2: Apply to given data

    For values 1,2,4,5,7:
    1's next is 2
    2's next is 4
    4's next is 5
    5's next is 7
    7 has no next, so null
  3. Final Answer:

    [{num:1, next_num:2}, {num:2, next_num:4}, {num:4, next_num:5}, {num:5, next_num:7}, {num:7, next_num:null}] -> Option A
  4. Quick Check:

    LEAD() shifts values down by one [OK]
Hint: LEAD() shows next row's value or null if none [OK]
Common Mistakes:
  • Assuming LEAD() repeats current value
  • Expecting gaps filled automatically
  • Confusing LEAD() with LAG()
4. The following query is intended to find gaps in the num sequence but returns no rows:
SELECT num FROM numbers WHERE LEAD(num) OVER (ORDER BY num) - num > 1;

What is the error?
medium
A. You cannot use window functions directly in WHERE clause
B. The ORDER BY inside LEAD() is missing
C. The subtraction operator is invalid here
D. LEAD() requires a GROUP BY clause

Solution

  1. Step 1: Understand window function restrictions

    Window functions like LEAD() cannot be used directly in the WHERE clause because WHERE filters rows before window functions are applied.
  2. Step 2: Correct approach

    Use a subquery or CTE to compute LEAD() first, then filter in an outer query.
  3. Final Answer:

    You cannot use window functions directly in WHERE clause -> Option A
  4. Quick Check:

    Window functions not allowed in WHERE [OK]
Hint: Use subquery or CTE to filter on window function results [OK]
Common Mistakes:
  • Trying to filter window function in WHERE
  • Missing OVER clause
  • Expecting LEAD() to work like aggregate
5. You have a table orders with an integer column order_id that should be sequential but may have missing numbers. Which query correctly finds all missing order_id values between the minimum and maximum present?
hard
A. SELECT order_id FROM orders WHERE LEAD(order_id) - order_id > 1;
B. SELECT DISTINCT order_id + 1 FROM orders WHERE order_id + 1 NOT IN (SELECT order_id FROM orders);
C. SELECT order_id FROM orders WHERE order_id NOT IN (SELECT order_id FROM orders);
D. WITH seq AS (SELECT generate_series(MIN(order_id), MAX(order_id)) AS id FROM orders) SELECT id FROM seq LEFT JOIN orders ON seq.id = orders.order_id WHERE orders.order_id IS NULL;

Solution

  1. Step 1: Generate full sequence range

    Use generate_series from minimum to maximum order_id to create all possible IDs.
  2. Step 2: Find missing IDs by left join

    Left join this sequence to existing orders and select IDs where no matching order exists (NULL in orders).
  3. Final Answer:

    WITH seq AS (SELECT generate_series(MIN(order_id), MAX(order_id)) AS id FROM orders) SELECT id FROM seq LEFT JOIN orders ON seq.id = orders.order_id WHERE orders.order_id IS NULL; -> Option D
  4. Quick Check:

    Generate full range, then find missing with LEFT JOIN [OK]
Hint: Generate full range then find missing with LEFT JOIN [OK]
Common Mistakes:
  • Using LEAD() alone misses multiple gaps
  • Incorrect NOT IN subquery logic
  • Assuming order_id + 1 always missing
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard