2017-05-26 14 views
0

私はidとparent_idのテーブルを持っています。私はツリーの生成方法について多くのCTEを見てきました。しかし、私はそれから任意のノードを与えられたフルツリーを取得するためにツリーをフィルタリングするように見えることはできません。私がidで値1,2,3または4のいずれかのIツリー5又は6sql serverどの子供が与えられたフルツリーを取得する方法?

5, NULL 
6, 5 
ため

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

を取得する必要をフィルタリングした場合の値

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

考える

7, NULL 

これはCTEを使用して達成できますか?

答えて

2

いずれかを使用CTEは、ツリーのルートを見つけて、ツリー構造を爆発するために第2の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 

がうまくいけば、あなたはどのように見ることができる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

関連する問題