3

I次の形式の表があります。これは、各レコードが親レコードを指す自己参照表です。階層テーブル(自己参照表)のロールアップ数

NODE_ID PARENT_ID COUNT 
1  0   NULL 
2  1   NULL 
3  2   10 
4  2   12 
5  0   NULL 
6  5   NULL 
7  6   NULL 
8  7   12 

出力を下位の形式にします。親の数は、葉の子の数の合計にする必要があります。 注:葉の子のみがカウントを含みます。私は両親にそれを巻き上げたい。

NODE_ID PARENT_ID COUNT 
1  0   22 
2  1   22 
3  2   10 
4  2   12 
5  0   12 
6  5   12 
7  6   12 
8  7   12 

助けてください。

+0

@GiorgosBetsos出力を誤解していると思います。ノード「2」は合計カウントが「22」の2つの子を有する。次に、ノード「1」は、「22」のカウントを有する子供として「2」のみを有する。おそらく、ある種の再帰的なクエリが必要になるでしょう。 –

+0

@Tim Biegeleisenあなたは正しいです。私は直接的な子供の数の合計が欲しいです。 – gkarya42

答えて

0

まあ、私は単純に何も考えませんでした:

;WITH GetLevelsCTE AS (
    SELECT NODE_ID, PARENT_ID, COUNT, level = 1, ROOT = NODE_ID 
    FROM mytable 
    WHERE PARENT_ID = 0 

    UNION ALL 

    SELECT t1.NODE_ID, t1.PARENT_ID, t1.COUNT, level = t2.level + 1, t2.ROOT 
    FROM mytable AS t1 
    JOIN GetLevelsCTE AS t2 ON t2.NODE_ID = t1.PARENT_ID 
), MaxLevelCTE AS (
    -- Get MAX level per root NODE_ID 
    SELECT MAX(level) AS max_level, ROOT 
    FROM GetLevelsCTE 
    GROUP BY ROOT 
), GetCountCTE AS (
    -- Anchor query: start from the bottom 
    SELECT t1.NODE_ID, t1.PARENT_ID, t1.COUNT, t1.level 
    FROM GetLevelsCTE AS t1 
    JOIN MaxLevelCTE AS t2 ON t1.ROOT = t2.ROOT 
    WHERE t1.level = t2.max_level 

    UNION ALL 

    -- Recursive query: get counts of next level 
    SELECT t1.NODE_ID, t1.PARENT_ID, t2.COUNT, t1.level 
    FROM GetLevelsCTE AS t1 
    JOIN GetCountCTE AS t2 ON t1.level = t2.level - 1 AND t1.NODE_ID = t2.PARENT_ID 
) 
SELECT NODE_ID, PARENT_ID, SUM(COUNT) AS COUNT 
FROM GetCountCTE 
GROUP BY NODE_ID, PARENT_ID 
ORDER BY NODE_ID 

短い説明:ツリーのすべてのノードにlevel番号を割り当てるために使用される

  • GetLevelsCTE
  • MaxLevelCTEは、前のCTEを使用して、ツリーの最大レベルを取得します。
  • GetCountCTEは、木を下から親ノードにトラバースするために、前にCTEsの両方を使用します。このようにして、COUNTが親ノードに伝播されます。
+0

:ありがとうございます。クエリの階層レベルが1つしかない場合にのみクエリが有効です。同じテーブルに2つのトップレベルの親がある場合(親または親のIDが0のノード)、それはうまくいかないでしょう。 – gkarya42

+0

質問表を更新しました。親id 0は、ツリー階層のルートを意味します。 – gkarya42

+0

私の間違いは、テーブル内のツリーの部門が異なっている場合、問題は複製されます。 – gkarya42