web-dev-qa-db-ja.com

すべてのノードのすべての親/子孫をリストする

私は次の構造を持っています:

ツリーの例:

Tree Diagram

テーブルの例:

    [table]

    id  parent
    ----------
    1   NULL
    2   1
    3   1
    4   2
    5   2
    6   2
    7   3
    8   4

それぞれのidについて、その子孫を含むすべての親を別の行にリストします。

望ましい出力:

    id  parent
    ----------
    1   NULL
    2   1
    3   1
    4   1
    4   2
    5   1
    5   2
    6   1
    6   2
    7   1
    7   3
    8   1
    8   2
    8   4

CTEを使用しようとしましたが、頭を包むようには見えません。

    with temp(id,parent) as (
    SELECT S.id, S.parent
    FROM [table] as S 

    UNION ALL

    SELECT S2.id, S2.parent
    FROM [table] as S2 
    inner join temp on S2.id=temp.parent and temp.id is not null
    )

    SELECT * FROM temp order by id

階層ツリーを上に移動して、ヒットしたすべてのノードを、ツリーのすべての開始点について別の行にリストしようとしています。これがサンプルデータの提供方法です。

6
Matthew Davons

あなたは正しい道を進んでいて、ほとんどそれを持っていました。 2番目のセクションの選択では、親列はS2ではなくcteから取得する必要があり、2番目のセクションでも結合は逆方向(S2.id = p.parentS2.parent = p.id)。しかし、それだけです!

create table [table]
(
id int,
parent int
);

insert into [table] values(1,NULL),
    (2,1),
    (3,1),
    (4,2),
    (5,2),
    (6,2),
    (7,3),
    (8,4);


;WITH ctetable(id, parent, depth, path) as 
(
    SELECT S.id, S.parent, 1 AS depth, convert(varchar(100), S.id) AS path
    FROM [table] as S
    UNION ALL
    SELECT S2.id, p.parent, p.depth + 1 AS depth, convert(varchar(100), (RTRIM(p.path) +'->'+ convert(varchar(100), S2.id)))
    FROM ctetable AS p JOIN [table] as S2 on S2.parent = p.id
    WHERE p.parent is not null
)
SELECT * FROM ctetable ORDER BY id, parent;
9
indiri