Recursive Common Table Expressions (CTEs) are a powerful feature in SQL that allows you to write queries for hierarchical or self-referential data. Unlike regular CTEs, recursive CTEs enable repeated references to themselves within their definition, making them particularly useful for problems such as navigating organizational hierarchies, processing tree structures, and handling recursive relationships.
A Recursive CTE is a type of CTE that references itself within its definition. It is designed to solve problems involving hierarchical or recursive data structures, such as:
The basic syntax of a recursive CTE is:
WITH cte_name (optional_column_names) AS (
-- Anchor Query
initial_query
UNION ALL
-- Recursive Query
recursive_query_reference_to_cte_name
)
SELECT *
FROM cte_name;
We have an employees
table:
EmployeeID | Name | ManagerID |
---|---|---|
1 | Alice | NULL |
2 | Bob | 1 |
3 | Charlie | 1 |
4 | David | 2 |
5 | Eve | 2 |
WITH EmployeeHierarchy AS (
-- Anchor Query
SELECT EmployeeID, Name, ManagerID, 1 AS Level
FROM employees
WHERE ManagerID IS NULL
UNION ALL
-- Recursive Query
SELECT e.EmployeeID, e.Name, e.ManagerID, eh.Level + 1
FROM employees e
INNER JOIN EmployeeHierarchy eh ON e.ManagerID = eh.EmployeeID
)
SELECT *
FROM EmployeeHierarchy;
EmployeeID | Name | ManagerID | Level |
---|---|---|---|
1 | Alice | NULL | 1 |
2 | Bob | 1 | 2 |
3 | Charlie | 1 | 2 |
4 | David | 2 | 3 |
5 | Eve | 2 | 3 |
WITH Numbers AS (
-- Anchor Query
SELECT 1 AS Number
UNION ALL
-- Recursive Query
SELECT Number + 1
FROM Numbers
WHERE Number < 10
)
SELECT *
FROM Numbers;
Number |
---|
1 |
2 |
3 |
... |
10 |
DirectoryID | Name | ParentID |
---|---|---|
1 | Root | NULL |
2 | Folder A | 1 |
3 | Folder B | 1 |
4 | Subfolder1 | 2 |
WITH DirectoryTree AS (
-- Anchor Query
SELECT DirectoryID, Name, ParentID, 1 AS Depth
FROM directories
WHERE ParentID IS NULL
UNION ALL
-- Recursive Query
SELECT d.DirectoryID, d.Name, d.ParentID, dt.Depth + 1
FROM directories d
INNER JOIN DirectoryTree dt ON d.ParentID = dt.DirectoryID
)
SELECT *
FROM DirectoryTree;
WITH Numbers AS (
SELECT 1 AS Number
UNION ALL
SELECT Number + 1
FROM Numbers
WHERE Number < 100 AND Number < 10
)
SELECT *
FROM Numbers;
Feature | Recursive CTEs | Loops in Stored Procedures | Temporary Tables |
---|---|---|---|
Readability | High | Moderate | Moderate |
Performance | Moderate | High | Moderate |
Flexibility | High | High | Moderate |
WITH Factorial AS (
SELECT 1 AS Number, 1 AS Factorial
UNION ALL
SELECT Number + 1, Factorial * (Number + 1)
FROM Factorial
WHERE Number < 5
)
SELECT *
FROM Factorial;
Number | Factorial |
---|---|
1 | 1 |
2 | 2 |
3 | 6 |
4 | 24 |
5 | 120 |
Recursive CTEs are an essential SQL tool for handling hierarchical data, generating sequences, and solving recursive problems elegantly. By understanding their syntax, limitations, and use cases, you can leverage recursive CTEs to write powerful and efficient queries. Happy Coding!❤️