2017-05-26 54 views
0

我有一個id和parent_id表。我已經看到許多CTE如何生成樹。然而,我似乎無法過濾樹,以便從其中獲取任何節點的完整樹。sql server如何檢索給定的任何孩子的完整樹?

給出的值

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

使用一個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

你可以像這樣使用遞歸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

相關問題