We use recursive CTEs to create a list of numbers or dates step-by-step inside the database. This helps when you need a sequence of values without having a table ready.
Recursive CTE for series generation in SQL
WITH RECURSIVE series_name(column_name) AS ( -- Anchor member: starting point SELECT start_value UNION ALL -- Recursive member: adds next value SELECT column_name + step_value FROM series_name WHERE column_name < end_value ) SELECT * FROM series_name;
The WITH RECURSIVE starts the recursive query.
The anchor member sets the first value in the series.
WITH RECURSIVE numbers(n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM numbers WHERE n < 5 ) SELECT * FROM numbers;
WITH RECURSIVE dates(d) AS ( SELECT DATE('2024-01-01') UNION ALL SELECT DATE(d, '+1 day') FROM dates WHERE d < DATE('2024-01-05') ) SELECT * FROM dates;
WITH RECURSIVE empty_series(n) AS ( SELECT 1 WHERE 1 > 5 UNION ALL SELECT n + 1 FROM empty_series WHERE n < 5 ) SELECT * FROM empty_series;
This query creates a series of numbers from 1 to 10 using a recursive CTE.
WITH RECURSIVE number_series(num) AS ( SELECT 1 UNION ALL SELECT num + 1 FROM number_series WHERE num < 10 ) SELECT * FROM number_series;
Time complexity is roughly O(n) where n is the number of values generated.
Space complexity depends on how many rows the series produces; large series can use more memory.
Common mistake: forgetting the stopping condition in the recursive part causes infinite loops.
Use recursive CTEs when you don't have a ready table of numbers or dates and want to generate sequences on the fly.
Recursive CTEs help generate sequences step-by-step inside SQL.
Always include a stopping condition to avoid infinite loops.
Useful for creating number or date lists without extra tables.
Practice
Recursive CTE in SQL for series generation?Solution
Step 1: Understand Recursive CTE usage
Recursive CTEs are used to repeatedly execute a query to build results step-by-step.Step 2: Identify series generation purpose
They are commonly used to generate sequences like numbers or dates without needing extra tables.Final Answer:
To generate a sequence of numbers or dates step-by-step within a query -> Option AQuick Check:
Recursive CTE = sequence generation [OK]
- Confusing recursive CTE with JOIN operations
- Thinking recursive CTE deletes duplicates
- Assuming recursive CTE creates indexes
numbers generating numbers from 1?Solution
Step 1: Check correct WITH RECURSIVE syntax
The correct syntax starts withWITH RECURSIVE cte_name AS ( ... ).Step 2: Validate the recursive query structure
WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) correctly usesSELECT 1 AS numas anchor and recursive part withUNION ALLand stopping condition.Final Answer:
WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) -> Option BQuick Check:
Correct recursive CTE syntax = WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) [OK]
- Placing RECURSIVE after CTE name
- Missing parentheses around CTE query
- Omitting AS keyword
WITH RECURSIVE seq AS ( SELECT 1 AS n UNION ALL SELECT n + 2 FROM seq WHERE n < 7 ) SELECT * FROM seq;
What will be the output rows?
Solution
Step 1: Analyze anchor and recursive step
Anchor row is 1. Recursive step adds 2 each time: 1, 3, 5, 7.Step 2: Check stopping condition
Recursion stops when n < 7 is false. Since 7 is included, sequence ends at 7.Final Answer:
[1, 3, 5, 7] -> Option CQuick Check:
Start=1, step=+2, stop at 7 = [1,3,5,7] [OK]
- Assuming step is 1 instead of 2
- Stopping before reaching 7
- Including numbers beyond 7
WITH RECURSIVE count_up AS ( SELECT 1 AS num UNION ALL SELECT num + 1 FROM count_up ) SELECT * FROM count_up WHERE num <= 3;
Solution
Step 1: Check recursive part for stopping condition
The recursive SELECT lacks a WHERE clause to stop recursion, causing infinite loop.Step 2: Understand WHERE clause placement
The WHERE clause outside the CTE filters final results but does not stop recursion inside CTE.Final Answer:
Missing stopping condition inside the recursive part causing infinite recursion -> Option DQuick Check:
Stopping condition must be inside recursive CTE [OK]
- Placing stopping condition only in final SELECT
- Confusing UNION and UNION ALL effects
- Incorrect alias usage
Solution
Step 1: Understand date addition syntax
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT dt + INTERVAL '1 day' FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; usesdt + INTERVAL '1 day'which is standard SQL for adding one day to a date.Step 2: Check stopping condition and anchor
Anchor selects the start date as DATE type. Recursive part adds one day while date is less than '2024-01-05'.Step 3: Compare other options
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT DATE(dt, '+1 day') FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; uses SQLite styleDATE(dt, '+1 day'), which is not standard SQL. WITH RECURSIVE dates AS (SELECT '2024-01-01' AS dt UNION ALL SELECT dt + INTERVAL 1 DAY FROM dates WHERE dt <= '2024-01-05') SELECT * FROM dates; uses incorrect WHERE condition allowing extra date. WITH RECURSIVE dates AS (SELECT '2024-01-01' AS dt UNION ALL SELECT dt + 1 FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; adds integer to date incorrectly.Final Answer:
WITH RECURSIVE dates AS (SELECT DATE('2024-01-01') AS dt UNION ALL SELECT dt + INTERVAL '1 day' FROM dates WHERE dt < '2024-01-05') SELECT * FROM dates; -> Option AQuick Check:
Date + INTERVAL '1 day' is standard SQL date addition [OK]
- Using database-specific date functions in standard SQL
- Incorrect stopping condition allowing extra dates
- Adding integer directly to date without INTERVAL
Ready to prove it?
Pass the test and this pattern moves unknown
