Еще одним вариантом является использование hierarcyid
типа данных
Пример
Declare @YourTable Table ([ID] int,[Caption] varchar(50),[Parent] int) Insert Into @YourTable Values
(1,'A',NULL)
,(2,'B',NULL)
,(3,'a',1)
,(4,'b',2)
,(5,'bb',4)
,(6,'C',NULL)
,(7,'aa',3)
,(8,'c',6)
;with cteP as (
Select ID
,Parent
,Caption
,HierID = convert(hierarchyid,concat('/',ID,'/'))
From @YourTable
Where Parent is null
Union All
Select ID = r.ID
,Parent = r.Parent
,Caption = r.Caption
,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
From @YourTable r
Join cteP p on r.Parent = p.ID)
Select Lvl = HierID.GetLevel()
,ID
,Parent
,Caption
From cteP A
Order By A.HierID
Возвращает
Lvl ID Parent Caption
1 1 NULL A
2 3 1 a
3 7 3 aa
1 2 NULL B
2 4 2 b
3 5 4 bb
1 6 NULL C
2 8 6 c