Примечание: финал, где закомментирована проиллюстрировать полную иерархию.
Создание демонстративных Таблица
Declare @YourTable table (Id int,Pt int, Level int, Placement int)
Insert Into @YourTable values
(47,-1, 0,0),
(23,47, 1,0),
(86,47, 1,1),
(5 ,23, 2,0),
(29,23, 2,1),
(68,86, 2,0),
(8 , 5, 3,1),
(31,29, 3,1),
(67,68, 3,0)
В SQL -
Declare @Top int = null --<< Sets top of Hier Try 5
Declare @MaxLvl int = 99
Declare @Nest varchar(25) = ' ' --<< Optional: Added for readability
;with cteHB (Seq,ID,Pt,Lvl,Title,Placement) as (
Select Seq = cast(1000+Row_Number() over (Order by ID) as varchar(500))
,ID
,Pt
,Lvl=1
,Title =concat('Item ',ID)
,Placement
From @YourTable Where (Pt=-1 and isnull(@Top,-1) =-1) or ([email protected] and isnull(@Top,0) <>0)
Union All
Select Seq = cast(concat(cteHB.Seq,'.',1000+Row_Number() over (Order by cteCD.ID)) as varchar(500))
,cteCD.ID
,cteCD.Pt
,cteHB.Lvl+1
,Title = concat('Item ',cteCD.ID)
,cteCD.Placement
From @YourTable cteCD
Join cteHB on cteCD.Pt = cteHB.ID and cteHB.Lvl+1<[email protected] and cteCD.Placement=0)
,cteR1 as (Select Seq,ID,R1=Row_Number() over (Order By Seq) From cteHB)
,cteR2 as (Select A.Seq,A.ID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.ID)
Select B.R1
,C.R2
,A.ID
,A.Pt
,A.Lvl
,Title = Replicate(@Nest,A.Lvl) + A.Title
,A.Placement
From cteHB A
Join cteR1 B on A.ID=B.ID
Join cteR2 C on A.ID=C.ID
--Where R1=R2
Order By B.R1
Возвращает
R1 R2 ID Pt Lvl Title Placement
1 9 47 -1 1 Item 47 0
2 6 23 47 2 Item 23 0
3 4 5 23 3 Item 5 0
4 4 8 5 4 Item 8 1
5 6 29 23 3 Item 29 1
6 6 31 29 4 Item 31 1
7 9 86 47 2 Item 86 1
8 9 68 86 3 Item 68 0
9 9 67 68 4 Item 67 0
У меня есть проблемы с пониманием, почему 8 не внизу слева и 62 справа внизу. если бы существовало 99, было бы это правильно? и если бы существовало 6, это было бы внизу слева? Я ничего не вижу в данных, имеющих левый правый ... или просто используя минимальную/максимальную работу над ID? – xQbert
@xQbert, чтобы получить нижнюю левую часть от 47, вам нужно продолжать перемещаться только к вашему левому ребенку и никогда не переходить к id с правой стороны. тот же для правого –
gotcha сейчас. Размещение 0 указывает, что слева 1 указывает на право. – xQbert