2016-06-24 6 views
1

これは、ノードのすべての親を見つける通常のCTEのバリエーションです。差異は共通表式(ルートが両方の列に存在しない場合)

  • nullの子はありません。代わりに、それは単にchildの列には存在しません。この場合

    insert into t (parent, child) values (1, 2) 
    insert into t (parent, child) values (1, 3) 
    insert into t (parent, child) values (4, 2) 
    insert into t (parent, child) values (2, 5) 
    insert into t (parent, child) values (2, 6) 
    insert into t (parent, child) values (9, 6) 
    insert into t (parent, child) values (6, 7) 
    insert into t (parent, child) values (6, 8) 
    
    with cte as 
    ( 
        select child, parent, 0 as level 
        from t 
        where parent = 5 
        union all 
        select q.child, q.parent, level+1 
        from t q 
        inner join cte as c on c.parent= q.child 
    ) 
    
    select distinct parent from cte 
    where parent <> 5 
    

    、私は5のためのすべての親を取得しようとすると、5は誰の親ではないので、何も見つからなかった:

は、ここに私の試みです。私が2のすべての親を見つけようとすると、256の親であるために成功します。

+0

これは、実行可能な階層ではありません。 2&6は子供の2倍です。私はおそらく、コピー/ペーストエラーであると考えているフィールド名を変更しました。あなたのcteは階層をbuldします、結果が好きではないかもしれません6人が最大の人口を持っていました –

+0

私は決してそれが木ではないと言いました。子供が複数の親を持つことはできない、または親は複数の子供を持つことはできません。 – jiaweizhang

+0

これはフリー/アドホックな階層であれば問題ありません。子供が複数の親を持つことができることに同意します(つまり、レポートはリスク分析と四半期結果に属します)。明らかに5は親ではない。 –

答えて

2

5が誰の親でもない場合、フィルタparent=5は決して出力しません。 5childであり、あなたはそれ以上のすべての親を見つけたい:

declare @t table (parent int, child int) 

insert into @t (parent, child) 
values (1, 2), 
(1, 3), 
(4, 2), 
(2, 5), 
(2, 6), 
(9, 6), 
(6, 7), 
(6, 8) 

;with cte as 
( 
    select child, parent, 0 as level 
    from @t 
    where child = 5 ---<<< 
    union all 
    select q.child, q.parent, level+1 
    from @t q 
    inner join cte as c on c.parent= q.child 
) 

select distinct parent from cte 
where parent <> 5 

enter image description here

+0

ああ。ありがとう。それは本当に私のことわざだった。 「親」を「子」に変更して機能しました。 – jiaweizhang

関連する問題