获取顶级父级ID继承给SQL中的所有子级

San*_*mas 2 sql common-table-expression sql-server-2012

我有这样的桌子

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
---------------------------------
Run Code Online (Sandbox Code Playgroud)

我需要像这样从其父代继承所有子代的代码

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
---------------------------------
Run Code Online (Sandbox Code Playgroud)

我在下面尝试了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
Run Code Online (Sandbox Code Playgroud)

这没有帮助我实现我正在尝试的东西。我只是CTE的初学者,我认为它无法解决。

Tim*_*sen 6

您使用了递归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;
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

演示版

递归CTE的基本情况部分(即联合之前发生的事情)应该是那些没有父项的记录。这就是我们知道他们是最高父母级别的方式。然后,我们通过将给定级别与紧接其上方的父级匹配来递归地加入CTE。然后,我们将使用技巧来降低顶层代码:

COALESCE(t1.Code, t2.Code)
Run Code Online (Sandbox Code Playgroud)

这将从父母的代码之一开始,然后向下传播到各个级别的孩子。