在Hierarchical表中获取子项的Root父项

时间:2014-07-02 05:35:40

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我有一个包含分层数据的表,结构如下:

ID      ParentId
----   ----------
1       NULL
2       1
3       2
4       2
5       3
6       5

如果我传递节点Id,我希望通过遍历SQL中的所有父节点来获取最顶层的节点ID /详细信息。

我试过CTE,我不知道怎么能得到正确的组合。但是,我把它作为一个功能工作,但它是如此缓慢,我不得不发布这个问题。

在上面的例子中,如果我通过6,我想要最高,即1.通过遍历6 => 5 => 3 => 2 => [1](结果)

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:5)

DECLARE @id INT = 6
;WITH parent AS
(
    SELECT id, parentId, 1 AS [level] from tbl WHERE id = @id
    UNION ALL 
    SELECT t.id, t.parentId, [level] + 1 FROM parent
    INNER JOIN tbl t ON t.id =  parent.parentid
)
SELECT TOP 1 id FROM parent ORDER BY [level] DESC

@ TechDo的答案假设最低ID将是父母。如果您不想依赖于此,则上述查询将按深度排序。

答案 1 :(得分:4)

请尝试:

declare @id int=6
;WITH parent AS
(
    SELECT id, parentId  from tbl WHERE id = @id
    UNION ALL 
    SELECT t.id, t.parentId FROM parent
    INNER JOIN tbl t ON t.id =  parent.parentid
)

SELECT TOP 1 id FROM  parent
order by id asc

答案 2 :(得分:2)

您可以尝试此查询我的朋友获取所有ID:

with tab1(ID,Parent_ID) as
(select * from table1 where id = 6
union all
select t1.* from table1 t1,tab1 
where tab1.Parent_ID = t1.ID)
select ID from tab1;

并且此查询将给出最终结果:

with tab1(ID,Parent_ID) as
(select * from table1 where id = 6
union all
select t1.* from table1 t1,tab1 
where tab1.Parent_ID = t1.ID)
select ID from tab1 where parent_id is null;

SQL Fiddle

答案 3 :(得分:1)

;WITH CTE
as
(
    Select I.ID,P.Parent_id
    from #temp I 
    join #temp P 
    on P.Id = I.Parent_Id
    where i.ID = 6
    union all
    Select I.ID,P.Parent_id
    from CTE I 
    join #temp P 
    on P.Id = I.Parent_Id
    where p.Parent_Id is not null
)
Select ID,min(parent_id) from CTE group by id;

答案 4 :(得分:0)

 WITH CTE_MyTable AS (
    SELECT        Id, ParentId, NULL As RootParent, 1 As Lvl
    FROM            dbo.Ministry
    UNION ALL
    SELECT        a.id, b.ParentId, a.ParentId As RootParent, Lvl + 1
    FROM            CTE_MyTableAS a INNER JOIN
                                               dbo.MyTableAS b ON a.ParentId = b.Id
)
, CTE_Ministry_RN AS  (
    SELECT Id, RootParent, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Lvl DESC) RN
    FROM CTE_Ministry
)

SELECT Id, ISNULL(RootParent, Id) As RootParent
FROM CTE_Ministry_RN
WHERE RN = 1