What is Recursive CTE?
A Recursive Common Table Expression (CTE) in SQL Server is a powerful feature that allows you to define a
CTE that references itself, creating a recursive loop that can be used to generate hierarchical or self-referencing data. This feature is particularly useful for querying data stored in a hierarchical or nested structure, such as organizational charts, tree structures, and bill-of-materials.
To use a
Recursive CTE, you must first define the base case or anchor member, which is the starting point of the recursion, and then define the recursive member, which is the self-referencing part of the query that generates additional rows based on the previous rows. The recursion continues until no more rows can be generated, or until a predefined maximum recursion level is reached.
Here's an example of a Recursive CTE that generates a list of all the employees and their managers in a fictional company:
WITH EmployeeHierarchy AS (
-- Anchor member: Select all employees without managers
SELECT EmployeeID, Name, ManagerID, 0 AS Level
WHERE ManagerID IS NULL
-- Recursive member: Select all employees who report to the previous level's managers
SELECT E.EmployeeID, E.Name, E.ManagerID, Level + 1
FROM Employees E
JOIN EmployeeHierarchy EH ON EH.EmployeeID = E.ManagerID
SELECT EmployeeID, Name, ManagerID, Level
ORDER BY Level, ManagerID, EmployeeID
In this example, the first part of the CTE selects all the employees who don't have a manager (i.e., they are at the top of the hierarchy), and assigns them a starting level of 0. The second part of the CTE recursively selects all the employees who report to the previous level's managers, and increments their level by 1. The final SELECT statement simply returns all the rows from the CTE, ordered by level, manager, and employee ID.
Recursive CTEs can be used to solve a wide range of problems, such as hierarchical queries, graph traversal, and pathfinding algorithms. However, it's important to be careful when using recursive CTEs as they can be computationally expensive and may cause performance issues on large datasets.