For building recursive queries In SQL Server 2005 we have to use a new functionality called Common Table Expressions.
Let's see how we can retrieve all the employees that report to a manager (ManagerID = 3) in the AdventureWorks database sample:
WITH CTE (EmployeeID, FullName, Title, ManagerID) AS
(
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
WHERE E.EmployeeID = 3
UNION ALL
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
INNER JOIN CTE ON E.ManagerID = CTE.EmployeeID
)
SELECT * FROM CTE
This query returns the following results:
|
EmployeeID |
Full Name |
Title |
ManagerID |
|
3 |
Roberto Tamburello |
Engineering Manager |
12 |
|
4 |
Rob Walters |
Senior Tool Designer |
3 |
|
9 |
Gail Erickson |
Design Engineer |
3 |
|
11 |
Jossef Goldberg |
Design Engineer |
3 |
|
158 |
Dylan Miller |
Research and Development Manager |
3 |
|
263 |
Ovidiu Cracium |
Senior Tool Designer |
3 |
|
267 |
Michael Sullivan |
Senior Design Engineer |
3 |
|
270 |
Sharon Salavaria |
Design Engineer |
3 |
|
5 |
Thierry D'Hers |
Tool Designer |
263 |
|
265 |
Janice Galvin |
Tool Designer |
263 |
|
79 |
Diane Margheim |
Research and Development Engineer |
158 |
|
114 |
Gigi Matthew |
Research and Development Engineer |
158 |
|
217 |
Michael Raheem |
Research and Development Manager |
158 |
If we don't want to return the manager we change the WHERE clause:
WITH CTE (EmployeeID, FullName, Title, ManagerID) AS
(
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
WHERE E.ManagerID = 3
UNION ALL
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
INNER JOIN CTE ON E.ManagerID = CTE.EmployeeID
)
SELECT * FROM CTE
And the results are:
|
EmployeeID |
Full Name |
Title |
ManagerID |
|
4 |
Rob Walters |
Senior Tool Designer |
3 |
|
9 |
Gail Erickson |
Design Engineer |
3 |
|
11 |
Jossef Goldberg |
Design Engineer |
3 |
|
158 |
Dylan Miller |
Research and Development Manager |
3 |
|
263 |
Ovidiu Cracium |
Senior Tool Designer |
3 |
|
267 |
Michael Sullivan |
Senior Design Engineer |
3 |
|
270 |
Sharon Salavaria |
Design Engineer |
3 |
|
5 |
Thierry D'Hers |
Tool Designer |
263 |
|
265 |
Janice Galvin |
Tool Designer |
263 |
|
79 |
Diane Margheim |
Research and Development Engineer |
158 |
|
114 |
Gigi Matthew |
Research and Development Engineer |
158 |
|
217 |
Michael Raheem |
Research and Development Manager |
158 |
If we want to get all the employees that an employee reports to, we just have to change the INNER JOIN order:
WITH CTE (EmployeeID, FullName, Title, ManagerID) AS
(
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
WHERE E.EmployeeID = 3
UNION ALL
SELECT E.EmployeeID, C.FirstName + ' ' + C.LastName FullName, E.Title, E.ManagerID
FROM HumanResources.Employee E
INNER JOIN Person.Contact C ON E.ContactID = C.ContactID
INNER JOIN CTE ON E.EmployeeID = CTE.ManagerID
)
SELECT * FROM CTE
And the employees that the employee (EmployeeID = 3) reports to are:
|
EmployeeID |
Full Name |
Title |
ManagerID |
|
3 |
Roberto Tamburello |
Engineering Manager |
12 |
|
12 |
Terri Duffy |
Vice President of Engineering |
109 |
|
109 |
Ken Sánchez |
Chief Executive Officer |
NULL |

![[FIX] BizTalk Server 2010, 2013, 2013 R2 & 2016 errors “Class not registered (WinMgmt)” or “Access denied”](https://blogit.create.pt/wp-content/uploads/2018/07/access-black-and-white-blur-270514-218x150.jpg)




















