1

任何ID自引用表我有一个包含下列数据的表:获取ID的整个产业链中给出的层次结构

+----+----------+ 
| ID | ParentID | 
+----+----------+ 
| 27 | 0  | 
| 38 | 27 | 
| 45 | 38 | 
| 86 | 0  | 
| 92 | 45 | 
| 48 | 86 | 
| 62 | 92 | 
| 50 | 62 | 
----------------- 

我希望能够通过任何 ID来一个存储过程,并获得该给定ID的ID(父母和子女)的整个链。

即。如果我通过ID = 45,我应该得到:

27 
38 
45 
92 
62 
50 

同样,如果我通过ID = 86,我应该得到:

86 
48 

任何帮助将不胜感激!

回答

1

您可以使用两个递归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 
+0

谢谢你的帮助Mikael。你的第一个解决方案返回了预期的结果 – 8thWonder 2011-06-12 17:37:57