您可以使用两个递归CTE。第一个找到根节点,第二个构建链。
declare @T table(ID int, ParentID int)
insert into @T values (27, 0), (38, 27), (45, 38), (86, 0),
(92, 45), (48, 86), (62, 92), (50, 62)
declare @ID int = 45
;with cte1 as
(
select T.ID, T.ParentID, 1 as lvl
from @T as T
where T.ID = @ID
union all
select T.ID, T.ParentID, C.lvl+1
from @T as T
inner join cte1 as C
on T.ID = C.ParentID
),
cte2 as
(
select T.ID, T.ParentID
from @T as T
where T.ID = (select top 1 ID
from cte1
order by lvl desc)
union all
select T.ID, T.ParentID
from @T as T
inner join cte2 as C
on T.ParentID = C.ID
)
select ID
from cte2
2版
有点短,查询计划提出更有效,但你永远不知道没有实际数据测试。
;with cte as
(
select T.ID, T.ParentID, ','+cast(@ID as varchar(max)) as IDs
from @T as T
where T.ID = @ID
union all
select T.ID, T.ParentID, C.IDs+','+cast(T.ID as varchar(10))
from @T as T
inner join cte as C
on (T.ID = C.ParentID or
T.ParentID = C.ID) and
C.IDs+',' not like '%,'+cast(T.ID as varchar(10))+',%'
)
select ID
from cte
谢谢你的帮助Mikael。你的第一个解决方案返回了预期的结果 – 8thWonder 2011-06-12 17:37:57