CTE in SQL
A recursive CTE is one that references itself within that CTE. The recursive CTE is useful when working with hierarchical data as the CTE continues to execute until the query returns the entire hierarchy.
A typical example of hierarchical data is a table that includes a list of employees. For every employee, the table provides a reference to that person’s manager. That reference is itself an employee ID within the same table. You can use a recursive CTE to display the hierarchy of employee data.
Example 1
EmployeeID int NOT NULL PRIMARY KEY,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
ManagerID int NULL
)
INSERT INTO Employees VALUES (1, 'Kent', 'Thompson', NULL)
WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1
FROM Employees
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
r.EmpLevel + 1
FROM Employees e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)
SELECT
FirstName + ' ' + LastName AS FullName, MgrID,
EmpLevel,
(SELECT FirstName + ' ' + LastName FROM Employees
FROM cteReports
Example 2
EmployeeID int NOT NULL PRIMARY KEY,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
ManagerID int NULL
)
INSERT INTO Employees1 VALUES (1, 'Kent', 'Thompson', NULL)
WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1
FROM Employees1
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
r.EmpLevel + 1
FROM Employees1 e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)
SELECT EmpID,
EmpLevel,
(SELECT FirstName + ' ' + LastName FROM Employees1
FROM cteReports
CREATE TABLE Employees2
EmployeeID int NOT NULL PRIMARY KEY,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
Department varchar(50) NOT NULL,
ManagerID int NULL
)
INSERT INTO Employees2 VALUES (1, 'Kent', 'Thompson', 'Finance', NULL)
WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel, Department)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1, Department
FROM Employees2
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID, r.EmpLevel + 1 , e.Department
FROM Employees2 e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)
SELECT EmpID,
EmpLevel, MgrID,
(SELECT FirstName + ' ' + LastName FROM Employees2
FROM cteReports