3

У меня есть таблица в нижерасположенном формате. Это самореляционная таблица, в которой каждая запись указывает на ее родительскую запись.Сводка числа сверток в иерархической таблице (самореляционная таблица)

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 

Я хочу выход быть в ниже format.The кол-родителя должны быть сумма подсчета листьев Чайлдс. Примечание: только дочерние элементы листа будут содержать счетчик. Я хочу свернуть его до родителей.

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'. В свою очередь, узел '1' имеет только« 2 »в качестве ребенка, у которого есть счетчик« 22 ». Вероятно, ему нужен рекурсивный запрос. –

+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 

Краткое объяснение:

  • GetLevelsCTE используется для назначения level номер для каждого узла дерева.
  • MaxLevelCTE использует предыдущий CTE, чтобы получить максимальный уровень дерева.
  • GetCountCTE использует оба предыдущих CTEs, чтобы пересечь дерево от нижнего к родительскому узлу. Таким образом, COUNT распространяется на родительский узел.
+0

: Спасибо за повторную игру. Ваш запрос действителен только в том случае, если существует только один уровень иерархии. Если в той же таблице у меня два родителя верхнего уровня (узел без родителей или родительский идентификатор 0), тогда это не сработает. Надеюсь, вы поняли мою озабоченность. – gkarya42

+0

Я обновил таблицу вопросов. Родительский id 0 означает корень иерархии деревьев. – gkarya42

+0

Моя ошибка, проблема реплицируется, если отдел деревьев в таблице отличается. Ответ на вопрос. – gkarya42