A Definitive Guide to MySQL Recursive CTE
A Recursive Common Table Expression (CTE) in MySQL is a type of CTE that allows a query to refer to itself. It is particularly useful for handling hierarchical or iterative data, such as organizational structures, graph traversal, or summing sequences.
Syntax
WITH RECURSIVE cte_name AS (
-- Anchor member (base case)
initial_query
UNION ALL
-- Recursive member (iterative case)
recursive_query
)
SELECT column1, column2, ...
FROM cte_name;
WITH RECURSIVE
: Declares the recursive CTE.- Anchor Member: The base case for recursion that initializes the result set.
- Recursive Member: Refers back to the CTE itself to process additional rows iteratively.
- Termination: Recursion stops when no new rows are returned.
Example Use Cases
Example 1: Hierarchical Data (Employee-Manager Relationship)
Consider the following employees
table:
id | name | manager_id |
---|---|---|
1 | Alice | NULL |
2 | Bob | 1 |
3 | Charlie | 1 |
4 | Diana | 2 |
5 | Edward | 2 |
Goal: Retrieve the hierarchy starting from a specific manager (e.g., Alice).
WITH RECURSIVE employee_hierarchy AS (
-- Anchor member
SELECT id, name, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL -- Start with top-level manager (Alice)
UNION ALL
-- Recursive member
SELECT e.id, e.name, e.manager_id, eh.level + 1
FROM employees e
JOIN employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT id, name, manager_id, level
FROM employee_hierarchy;
Result:
+----+---------+------------+-------+ | id | name | manager_id | level | +----+---------+------------+-------+ | 1 | Alice | NULL | 1 | | 2 | Bob | 1 | 2 | | 3 | Charlie | 1 | 2 | | 4 | Diana | 2 | 3 | | 5 | Edward | 2 | 3 | +----+---------+------------+-------+
Example 2: Summing a Sequence
Goal: Calculate the cumulative sum of numbers from 1 to 10.
WITH RECURSIVE sequence_sum AS (
-- Anchor member
SELECT 1 AS n, 1 AS cumulative_sum
UNION ALL
-- Recursive member
SELECT n + 1, cumulative_sum + (n + 1)
FROM sequence_sum
WHERE n < 10
)
SELECT n, cumulative_sum
FROM sequence_sum;
Result:
+----+----------------+ | n | cumulative_sum | +----+----------------+ | 1 | 1 | | 2 | 3 | | 3 | 6 | | 4 | 10 | | 5 | 15 | | 6 | 21 | | 7 | 28 | | 8 | 36 | | 9 | 45 | | 10 | 55 | +----+----------------+
Example 3: Fibonacci Sequence
Goal: Generate the Fibonacci sequence up to the 10th number.
WITH RECURSIVE fibonacci AS (
-- Anchor member
SELECT 1 AS position, 0 AS value, 1 AS next_value
UNION ALL
-- Recursive member
SELECT position + 1, next_value, value + next_value
FROM fibonacci
WHERE position < 10
)
SELECT position, value
FROM fibonacci;
Result:
+----------+-------+ | position | value | +----------+-------+ | 1 | 0 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 3 | | 6 | 5 | | 7 | 8 | | 8 | 13 | | 9 | 21 | | 10 | 34 | +----------+-------+
Key Considerations
Termination Condition:
- Recursive CTEs must have a termination condition to prevent infinite recursion. Use a
WHERE
clause in the recursive member to control the depth of recursion.
- Recursive CTEs must have a termination condition to prevent infinite recursion. Use a
Maximum Recursion Depth:
- MySQL limits the recursion depth to 1000 by default. You can adjust it using the
max_recursive_iterations
system variable:SET @@cte_max_recursion_depth = 2000;
- MySQL limits the recursion depth to 1000 by default. You can adjust it using the
Performance:
- Recursive CTEs can be resource-intensive. Optimize by reducing the number of iterations or filtering unnecessary data early.
Recursive CTE vs. Non-Recursive CTE
Feature | Recursive CTE | Non-Recursive CTE |
---|---|---|
Definition | Refers to itself within the query | Does not refer to itself |
Use Cases | Hierarchies, sequences, graphs | Simplifying complex queries |
Performance | Potentially slower for large data | Generally faster |
Complexity | More complex to write and debug | Easier to manage |
Advantages of Recursive CTEs
- Elegant Handling of Hierarchies:
- Simplifies queries for tree structures (e.g., employee-manager relationships).
- Dynamic Querying:
- Automatically handles varying levels of recursion without hardcoding depth.
- Improved Readability:
- Breaks down complex recursive logic into manageable components.
Limitations of Recursive CTEs
- Performance Overhead:
- Large datasets or deep recursion can slow down execution.
- Limited Depth:
- Constrained by the maximum recursion limit.
- Complex Debugging:
- Errors in recursive logic can be challenging to identify.
Use Cases
- Hierarchical Data:
- Employee-manager relationships, category hierarchies, etc.
- Pathfinding in Graphs:
- Shortest path, network traversals.
- Iterative Calculations:
- Fibonacci, summations, or other iterative math problems.
Performance Tips
- Optimize Base Query:
- Ensure the anchor member returns minimal, precise rows.
- Filter Early:
- Use
WHERE
clauses to limit rows processed in recursion.
- Use
- Analyze Execution:
- Use
EXPLAIN
to monitor performance bottlenecks.
- Use
Let me know if you need more examples or further clarification!