A Recursive CTE (Common Table Expression) is a query that refers to itself to repeatedly execute and build a result set step-by-step, often used to work with hierarchical or tree-structured data.
Click to reveal answer
beginner
What are the two main parts of a Recursive CTE?
1. Anchor member: The starting query that runs once. 2. Recursive member: The part that references the CTE itself to add more rows until a condition stops it.
Click to reveal answer
intermediate
How do you stop a Recursive CTE from running forever?
You include a condition in the recursive member that eventually stops adding new rows, preventing infinite loops.
Click to reveal answer
intermediate
Write a simple example of a Recursive CTE to generate numbers from 1 to 5.
WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) SELECT * FROM numbers;
Click to reveal answer
beginner
Why are Recursive CTEs useful for hierarchical data?
Because they can repeatedly join a table to itself to find parent-child relationships, making it easy to query trees like organization charts or folder structures.
Click to reveal answer
What keyword starts a Recursive CTE in MySQL?
ASTART RECURSIVE
BWITH RECURSIVE
CRECURSIVE CTE
DBEGIN RECURSIVE
✗ Incorrect
Recursive CTEs in MySQL start with the keyword 'WITH RECURSIVE'.
Which part of a Recursive CTE runs only once?
AAnchor member
BRecursive member
CTermination condition
DFinal SELECT
✗ Incorrect
The anchor member is the initial query that runs once to start the recursion.
What happens if a Recursive CTE has no stopping condition?
AIt returns an empty result
BIt returns only the anchor member rows
CIt runs forever causing an error
DIt runs once and stops
✗ Incorrect
Without a stopping condition, the recursion never ends and causes an error or infinite loop.
Which of these is a valid use case for Recursive CTEs?
AFiltering rows by date
BCalculating factorials
CSorting data alphabetically
DFlattening hierarchical data
✗ Incorrect
Recursive CTEs are great for working with hierarchical data like trees or organizational charts.
In the example: WITH RECURSIVE numbers AS (SELECT 1 AS num UNION ALL SELECT num + 1 FROM numbers WHERE num < 5) SELECT * FROM numbers; What is the output?
ANumbers 1 to 5
BOnly number 1
CNumbers 1 to 4
DNumbers 0 to 5
✗ Incorrect
The query generates numbers from 1 up to 5 inclusive.
Explain how a Recursive CTE works step-by-step.
Think about how the query builds results like climbing steps.
You got /4 concepts.
Describe a real-life example where Recursive CTEs can be useful.
Imagine a company with managers and employees.
You got /4 concepts.
Practice
(1/5)
1. What is the main purpose of a recursive CTE in MySQL?
easy
A. To create temporary tables for storing large datasets
B. To repeatedly execute a query to explore hierarchical or connected data
C. To speed up simple SELECT queries without joins
D. To permanently store data in the database
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 B
Quick Check:
Recursive CTE = hierarchical data exploration [OK]
Hint: Recursive CTEs repeat queries to explore connected data [OK]
Common Mistakes:
Confusing recursive CTEs with temporary tables
Thinking recursive CTEs speed up all queries
Assuming recursive CTEs permanently store data
2. Which of the following is the correct basic syntax to start a recursive CTE in MySQL?
easy
A. WITH cte_name RECURSIVE (anchor_query UNION recursive_query) SELECT * FROM cte_name;
B. CREATE RECURSIVE TABLE cte_name AS (anchor_query UNION recursive_query);
C. WITH RECURSIVE cte_name AS (anchor_query UNION ALL recursive_query) SELECT * FROM cte_name;
D. SELECT RECURSIVE * FROM cte_name WHERE condition;
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 C
Quick Check:
WITH RECURSIVE + UNION ALL = correct syntax [OK]
Hint: Look for WITH RECURSIVE and UNION ALL keywords [OK]
Common Mistakes:
Using UNION instead of UNION ALL in recursive part
Trying to CREATE RECURSIVE TABLE (not valid)
Misplacing RECURSIVE keyword after CTE name
3. Given the table 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;
medium
A. All employees who report directly or indirectly to employee with id 2
B. Only the employee with id 2
C. All employees who manage employee with id 2
D. Syntax error due to missing anchor query
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 A
Quick Check:
Recursive join on manager_id finds all subordinates [OK]
Hint: Recursive join on manager_id finds all subordinates [OK]
Common Mistakes:
Confusing manager and subordinate roles
Thinking it returns only direct reports
Assuming syntax error due to anchor query presence
4. Identify the error in this recursive CTE:
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;
medium
A. Anchor query should use WHERE parent_id = 0 instead of IS NULL
B. Recursive part should use LEFT JOIN instead of JOIN
C. CTE name cannot be 'cte', must be more descriptive
D. Missing UNION ALL causes infinite recursion or wrong results
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 D
Quick Check:
Recursive CTEs must use UNION ALL [OK]
Hint: Always use UNION ALL in recursive CTEs to avoid infinite loops [OK]
Common Mistakes:
Using UNION instead of UNION ALL in recursive CTE
Assuming NULL vs 0 matters for recursion logic
Thinking JOIN type affects recursion correctness
5. You want to list all ancestors of an employee in a company hierarchy stored in employees(id, manager_id, name). Which recursive CTE query correctly finds all managers up the chain for employee with id 5?
hard
A. 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;
B. 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.manager_id = a.id
)
SELECT * FROM ancestors WHERE id != 5;
C. WITH RECURSIVE ancestors AS (
SELECT id, manager_id, name FROM employees WHERE manager_id = 5
UNION ALL
SELECT e.id, e.manager_id, e.name FROM employees e
JOIN ancestors a ON e.manager_id = a.id
)
SELECT * FROM ancestors;
D. WITH RECURSIVE ancestors AS (
SELECT id, manager_id, name FROM employees WHERE id = 5
UNION
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;
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 A
Quick Check:
Join on e.id = a.manager_id moves up hierarchy [OK]
Hint: Join on e.id = a.manager_id to move up the hierarchy [OK]
Common Mistakes:
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
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.