Ini sepertinya berhasil. Kuncinya adalah menyadari bahwa kita dapat membangun jalan dengan cara mundur dan berhenti ketika kita tidak lagi memiliki orang tua untuk ditemukan:
DECLARE @t table (ID int not null, Name varchar(19) not null, ParentID int null)
insert into @t(ID,Name,ParentID) values
(1 ,'Alex',null),
(2 ,'John',null),
(3 ,'Don',1),
(4 ,'Philip',2),
(5 ,'Shiva',2),
(6 ,'San',3),
(7 ,'Antony',6),
(8 ,'Mathew',2),
(9 ,'Cyril',8),
(10,'Johan',9)
declare @search table (ID int not null)
insert into @search (ID) values (7),(10)
;With Paths as (
select s.ID as RootID,t.ID,t.ParentID,t.Name, CONVERT(varchar(max),t.Name) as Path
from
@search s
inner join
@t t
on
s.ID = t.ID
union all
select p.RootID,t.ID,t.ParentID,p.Name, t.Name + '->' + p.Path
from Paths p
inner join
@t t
on
p.ParentID = t.ID
)
select * from Paths where ParentID is null
Hasil:
RootID ID ParentID Name Path
----------- ----------- ----------- ------------------- ----------------------------
10 2 NULL Johan John->Mathew->Cyril->Johan
7 1 NULL Antony Alex->Don->San->Antony
(Saya telah meninggalkan kolom tambahan untuk membantu menunjukkan status akhir. Menanyakan CTE tanpa memfilter mungkin juga bersifat instruktif)
Saya juga memperingatkan bahwa saya biasanya tidak akan bekerja dengan string yang dibatasi jika memungkinkan - ini bukan representasi yang bagus ketika SQL Server memiliki tipe dirancang untuk bekerja dengan banyak nilai.