Получить родительский ID верхнего уровня для всех детей в SQL - PullRequest
2 голосов
/ 19 сентября 2019

У меня есть такая таблица

ID    Name     Parent    Code
----------------------------------
1     Item1     NULL     K123
2     Item2     NULL     K324
3     Item3      1       NULL
4     Item4      2       NULL
5     Item5      3       NULL
6     Item6      5       NULL
7     Item7      4       NULL
8     Item8      NULL    K567
9     Item9      8       NULL
10    Item10     NULL    NULL
---------------------------------

Мне нужно наследовать код всем дочерним элементам от его родителя, как это

ID    Name     Parent    Code
----------------------------------
1     Item1     NULL     K123
2     Item2     NULL     K324
3     Item3      1       K123
4     Item4      2       K324
5     Item5      3       K123
6     Item6      5       K123
7     Item7      4       K324
8     Item8      NULL    K567
9     Item9      8       K567
10    Item10     NULL    NULL
---------------------------------

Я попробовал CTE ниже

;with CTE(ID,Name,Parent,Code,[Level]) as
(
    select ID,Name,Parent,Code,0 as [Level] from tbl_mytable 
    union all
    select T.ID,T.Name,T.Parent,T.Code,C.[Level]+1 from tbl_mytable T
    inner join CTE C on C.Parent=T.ID
)
select * from CTE C

Что не помогает мне достичь того, что я пытаюсь.Я только начинающий с CTE, с которым я не думаю, что это может исправить.

1 Ответ

6 голосов
/ 19 сентября 2019

Вы были на правильном пути, чтобы использовать рекурсивный CTE, но ваша логика немного ошибочна.Рассмотрим эту рабочую версию:

WITH cte AS (
    SELECT * FROM tbl_mytable WHERE Parent IS NULL
    UNION ALL
    SELECT t1.ID, t1.Name, t1.Parent, COALESCE(t1.Code, t2.Code)
    FROM tbl_mytable t1
    INNER JOIN cte t2
        ON t1.Parent = t2.ID
)

SELECT *
FROM cte
ORDER BY ID;

enter image description here

Демо

БазаКомпонентом case рекурсивного CTE (то есть того, что предшествует объединению) должны быть записи, не имеющие родителей.Вот как мы знаем, что они наивысший родительский уровень.Затем мы присоединяемся к CTE рекурсивно, сопоставляя данный уровень родительскому элементу непосредственно над ним.Затем мы используем трюк для сброса кодов с верхнего уровня:

COALESCE(t1.Code, t2.Code)

Это начнется с одного из кодов родителя, а затем будет распространяться вниз на различные уровни потомков.

...