I have the below table
empid empname managerID
1 A NULL
2 B 1
3 C 1
4 D 2
Ok, so you asked for other ways. This is a little freaky.
CREATE TABLE employee (empid int, empname varchar(20), managerID int)
GO
insert into employee
select 1,'A',null union all
select 2,'B',1 union all
select 3,'C',1 union all
select 4,'D',2
GO
CREATE FUNCTION [dbo].[GetEmployeeTree](@ManagerId int)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN RETURN
(SELECT empID as '@Id',
empname AS '@Name',
dbo.GetEmployeeTree(empid)
FROM employee em
WHERE ManagerId=@ManagerId
FOR XML PATH('Employee'), TYPE)
END
GO
SELECT empID as '@Id',
empname AS '@Name',
dbo.GetEmployeeTree(empId)
FROM employee
WHERE managerId is null
FOR XML PATH('Employee'), ROOT('Employees')
Which gives this output
I have actually used this to generate large XML trees with tens of thousands of nodes and it is quite quick. There is probably a way to merge the root query with the child query, I just haven't quite figured that out yet. When I have used this technique in the past I have used a separate link and node table to define the hierarchy and it works a bit cleaner when you do that.