まあ、私は単純に何も考えませんでした:
;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
が親ノードに伝播されます。
@GiorgosBetsos出力を誤解していると思います。ノード「2」は合計カウントが「22」の2つの子を有する。次に、ノード「1」は、「22」のカウントを有する子供として「2」のみを有する。おそらく、ある種の再帰的なクエリが必要になるでしょう。 –
@Tim Biegeleisenあなたは正しいです。私は直接的な子供の数の合計が欲しいです。 – gkarya42