【问题标题】:Use a CTE to traverse to 2nd level in tree使用 CTE 遍历树中的第二层
【发布时间】:2013-09-25 08:25:13
【问题描述】:

我正在尝试使用 CTE 遍历 SQL Server 中的树。理想情况下,我想要的输出是一个表格,它为树中的每个节点显示树中从顶部起第二个对应的节点。

我有一些基本代码可以从给定节点遍历树,但是如何修改它以产生所需的输出?

DECLARE @temp TABLE 
(
  Id INT
, Name VARCHAR(50)
, Parent INT
)

INSERT @temp 
SELECT 1,' Great GrandFather Thomas Bishop', null UNION ALL
SELECT 2,'Grand Mom Elian Thomas Wilson' , 1 UNION ALL
SELECT 3, 'Dad James Wilson',2 UNION ALL
SELECT 4, 'Uncle Michael Wilson', 2 UNION ALL
SELECT 5, 'Aunt Nancy Manor', 2 UNION ALL
SELECT 6, 'Grand Uncle Michael Bishop', 1 UNION ALL
SELECT 7, 'Brother David James Wilson',3 UNION ALL
SELECT 8, 'Sister Michelle Clark', 3 UNION ALL
SELECT 9, 'Brother Robert James Wilson', 3 UNION ALL
SELECT 10, 'Me Steve James Wilson', 3 

;WITH cte AS 
(
    SELECT Id, Name, Parent, 1 as Depth
    FROM @temp
    WHERE Id = 8
    UNION ALL

    SELECT t2.*, Depth + 1 as 'Depth'
    FROM cte t
    JOIN @temp t2 ON t.Parent = t2.Id
 )
SELECT *
, MAX(Depth) OVER() - Depth + 1 AS InverseDepth
FROM cte

作为输出,我想要类似的东西

Id      Name                depth2_id  depth2_name
8       Sister Michelle ..  2          Grand Mom Elian ....
7       Brother David ..    2          Grand Mom Elian ....
4       Uncle Michael ..    2          Grand Mom Elian ...

感谢任何提示或指示。

【问题讨论】:

    标签: sql sql-server tsql tree common-table-expression


    【解决方案1】:

    有点难以达到你的目标,但你可以像这样使用 smth:

    ;with cte AS 
    (
        select
            t.Id, t.Name, t.Parent, 1 as Depth,
            null as Depth2Parent
        from @temp as t
        where t.Parent is null
    
        union all
    
        select
            t.Id, t.Name, t.Parent, c.Depth + 1 as 'Depth',
            isnull(c.Depth2Parent, case when c.Depth = 1 then t.Id end) as Depth2Parent
        from cte as c
            inner join @temp as t on t.Parent = c.Id
    )
    select *
    from cte
    

    sql fiddle demo

    【讨论】:

    • 谢谢,这与我想要的很接近,但我仍然有点挣扎。基本上我有一棵树,树的顶部节点是每个人的祖先,但我对树的第二层的祖先感兴趣。对于每个可能的子节点(可能位于不同的级别),我想在第二级找到它的祖先。我不太关心中间的节点,我更感兴趣的只是子节点及其对应的二级祖先。谢谢。
    • 我的代码完全符合您的要求。如果您不想看到顶部节点 - 您可以在最终选择中将其过滤掉
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 2012-01-01
    • 2022-11-11
    • 2017-05-28
    相关资源
    最近更新 更多