Recursive CTE for series generation in SQL - Time & Space Complexity
When we use a recursive CTE to generate a series, we want to know how the work grows as the series gets longer.
We ask: How many steps does the database take as the number of items in the series increases?
Analyze the time complexity of the following code snippet.
WITH RECURSIVE series AS (
SELECT 1 AS num
UNION ALL
SELECT num + 1 FROM series WHERE num < 1000
)
SELECT * FROM series;
This code generates numbers from 1 up to 1000 using recursion.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive step that adds 1 to the previous number.
- How many times: This step repeats once for each number from 2 to 1000, so about 999 times.
Each new number requires one recursive step, so the total steps grow directly with the size of the series.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 steps |
| 100 | 100 steps |
| 1000 | 1000 steps |
Pattern observation: The number of steps grows in a straight line as the series gets longer.
Time Complexity: O(n)
This means the work grows directly in proportion to how many numbers we want to generate.
[X] Wrong: "Recursive CTEs run in constant time no matter the series length."
[OK] Correct: Each recursive step adds one more number, so more numbers mean more steps and more work.
Understanding how recursive queries grow helps you explain efficiency clearly and shows you know how databases handle repeated work.
"What if we changed the recursion to generate numbers by adding 2 each time instead of 1? How would the time complexity change?"
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
