Recursive CTEs in MySQL - Time & Space Complexity
Recursive CTEs run queries that call themselves repeatedly to build results step by step.
We want to know how the time needed grows as the data or recursion depth grows.
Analyze the time complexity of the following recursive CTE in MySQL.
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 5
)
SELECT * FROM numbers;
This query generates numbers from 1 to 5 by repeatedly adding 1 until it reaches 5.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive step that adds 1 to the previous number.
- How many times: The recursion runs once for each number from 1 up to 5.
Each recursive call adds one more number until the limit is reached.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 recursive steps |
| 100 | 100 recursive steps |
| 1000 | 1000 recursive steps |
Pattern observation: The number of operations grows directly with the number of recursive steps.
Time Complexity: O(n)
This means the time needed grows linearly as the recursion depth or input size increases.
[X] Wrong: "Recursive CTEs run all steps at once, so time stays the same no matter the input size."
[OK] Correct: Each recursive step depends on the previous one, so the query runs more steps as the input grows, increasing time.
Understanding recursive CTE time helps you explain how queries scale and shows you can reason about complex SQL operations.
"What if we changed the recursion to add 2 each time instead of 1? How would the time complexity change?"
Practice
Solution
Step 1: Understand recursive CTE concept
A recursive CTE runs a base query and then repeatedly runs a recursive part referring back to itself to explore connected data.Step 2: Identify the purpose
This process is mainly used to handle hierarchical or tree-like data, such as organizational charts or folder structures.Final Answer:
To repeatedly execute a query to explore hierarchical or connected data -> Option BQuick Check:
Recursive CTE = hierarchical data exploration [OK]
- Confusing recursive CTEs with temporary tables
- Thinking recursive CTEs speed up all queries
- Assuming recursive CTEs permanently store data
Solution
Step 1: Recall MySQL recursive CTE syntax
MySQL uses the keyword WITH RECURSIVE followed by the CTE name and a query combining an anchor and recursive part with UNION ALL.Step 2: Match syntax options
WITH RECURSIVE cte_name AS (anchor_query UNION ALL recursive_query) SELECT * FROM cte_name; correctly shows this syntax, including UNION ALL and the final SELECT from the CTE.Final Answer:
WITH RECURSIVE cte_name AS (anchor_query UNION ALL recursive_query) SELECT * FROM cte_name; -> Option CQuick Check:
WITH RECURSIVE + UNION ALL = correct syntax [OK]
- Using UNION instead of UNION ALL in recursive part
- Trying to CREATE RECURSIVE TABLE (not valid)
- Misplacing RECURSIVE keyword after CTE name
employees(id, manager_id, name), what will this query return?WITH RECURSIVE subordinates AS ( SELECT id, name FROM employees WHERE id = 2 UNION ALL SELECT e.id, e.name FROM employees e JOIN subordinates s ON e.manager_id = s.id ) SELECT * FROM subordinates;
Solution
Step 1: Analyze anchor query
The anchor selects the employee with id = 2 as the starting point.Step 2: Analyze recursive part
The recursive part joins employees whose manager_id matches the current subordinates' id, thus finding direct reports, then their reports, and so on.Step 3: Understand final output
The query returns employee 2 and all employees reporting to them directly or indirectly.Final Answer:
All employees who report directly or indirectly to employee with id 2 -> Option AQuick Check:
Recursive join on manager_id finds all subordinates [OK]
- Confusing manager and subordinate roles
- Thinking it returns only direct reports
- Assuming syntax error due to anchor query presence
WITH RECURSIVE cte AS ( SELECT id FROM items WHERE parent_id IS NULL UNION SELECT i.id FROM items i JOIN cte ON i.parent_id = cte.id ) SELECT * FROM cte;
Solution
Step 1: Check recursive CTE syntax
Recursive CTEs require UNION ALL to combine anchor and recursive parts to avoid duplicate elimination.Step 2: Understand effect of UNION vs UNION ALL
Using UNION removes duplicates each iteration, which can cause infinite recursion or incorrect results in recursive queries.Final Answer:
Missing UNION ALL causes infinite recursion or wrong results -> Option DQuick Check:
Recursive CTEs must use UNION ALL [OK]
- Using UNION instead of UNION ALL in recursive CTE
- Assuming NULL vs 0 matters for recursion logic
- Thinking JOIN type affects recursion correctness
employees(id, manager_id, name). Which recursive CTE query correctly finds all managers up the chain for employee with id 5?Solution
Step 1: Understand the goal
We want to find all managers (ancestors) of employee 5, moving up the chain via manager_id.Step 2: Analyze join condition
To move up, join employees where employee id matches the manager_id of current ancestor (e.id = a.manager_id).Step 3: Check anchor and recursive parts
Anchor selects employee 5; recursive part finds their manager, then that manager's manager, etc.Final Answer:
WITH RECURSIVE ancestors AS (SELECT id, manager_id, name FROM employees WHERE id = 5 UNION ALL SELECT e.id, e.manager_id, e.name FROM employees e JOIN ancestors a ON e.id = a.manager_id) SELECT * FROM ancestors WHERE id != 5; -> Option AQuick Check:
Join on e.id = a.manager_id moves up hierarchy [OK]
- Reversing join condition to move down instead of up
- Using UNION instead of UNION ALL causing errors
- Starting anchor with manager_id = 5 instead of id = 5
Ready to prove it?
Pass the test and this pattern moves unknown
