sql server如何检索给定任何子项的完整树?

时间:2017-05-26 06:54:46

标签: sql-server tsql tree

我有一个id和parent_id的表。我已经看到很多关于如何生成树的CTE。但是我似乎无法过滤树,以便从给定任何节点的位置检索完整的树。

给出值

1, NULL
2, 1
3, 2
4, 2
5, NULL
6, 5
7, NULL

如果我按ID过滤任何值1,2,3或4,我应该得到树

1, NULL
2, 1
3, 2
4, 2

为5或6

5, NULL
6, 5

for 7

7, NULL

可以使用CTE实现吗?

2 个答案:

答案 0 :(得分:2)

使用一个CTE定位树的根,然后使用第二个CTE来爆炸树结构:

declare @T table (ID int not null, Parent int null)

insert into @T(ID,Parent) values
(1, NULL),
(2, 1   ),
(3, 2   ),
(4, 2   ),
(5, NULL),
(6, 5   ),
(7, NULL)

declare @Node int
set @node = 3

;With Root as (
    select t.ID,t.Parent from @T t where t.ID = @Node or t.Parent = @Node
    union all
    select t.ID,t.Parent
    from
        Root r
            inner join
        @t t
            on
                t.ID = r.Parent
), Tree as (
    select ID,Parent from Root where Parent is null
    union all
    select t.ID,t.Parent
    from @T t
        inner join
        Tree tr
            on tr.ID = t.Parent
)
select * from Tree

结果:

ID          Parent
----------- -----------
1           NULL
2           1
3           2
4           2

希望你能看到两个CTE如何在相反的方向上工作。

答案 1 :(得分:1)

您可以像这样使用递归CTE。 CTE使用RootId返回所有树,您可以通过其RootId

获取所有树节点
DECLARE @SampleData AS TABLE
(
    NodeId int,
    ParentNodeId int
)

INSERT INTO @SampleData
(
    NodeId,
    ParentNodeId
)
VALUES
( 1, NULL),
( 2, 1),
( 3, 2),
( 4, 2),
( 5, NULL),
( 6, 5),
( 7, NULL)

DECLARE @NodeId int = 4

-- temp returns all child nodes of rootid (1,5,7)
;WITH temp AS
(
    SELECT sd.NodeId, sd.ParentNodeId, sd.NodeId AS RootId 
    FROM @SampleData sd
    WHERE sd.ParentNodeId IS NULL

    UNION ALL

    SELECT sd.NodeId, sd.ParentNodeId, t.RootId  
    FROM temp t
    INNER JOIN @SampleData sd ON t.NodeId = sd.ParentNodeId
)

SELECT t2.NodeId, t2.ParentNodeId 
FROM temp t
INNER JOIN temp t2 ON t2.RootId = t.RootId
WHERE t.NodeId = @NodeId
OPTION (MAXRECURSION 0)

演示链接:http://rextester.com/PPPMXX4941