列出所有节点的所有父节点/上升节点

Mat*_*ons 8 sql-server cte sql-server-2014

我有以下结构:

示例树:

树状图

示例表:

    [table]

    id  parent
    ----------
    1   NULL
    2   1
    3   1
    4   2
    5   2
    6   2
    7   3
    8   4
Run Code Online (Sandbox Code Playgroud)

对于每个id,我想在单独的行中列出它的所有父母,包括它的后代。

期望输出:

    id  parent
    ----------
    1   NULL
    2   1
    3   1
    4   1
    4   2
    5   1
    5   2
    6   1
    6   2
    7   1
    7   3
    8   1
    8   2
    8   4
Run Code Online (Sandbox Code Playgroud)

我尝试使用 CTE,但我似乎无法理解它。

    with temp(id,parent) as (
    SELECT S.id, S.parent
    FROM [table] as S 

    UNION ALL
    
    SELECT S2.id, S2.parent
    FROM [table] as S2 
    inner join temp on S2.id=temp.parent and temp.id is not null
    )
    
    SELECT * FROM temp order by id
Run Code Online (Sandbox Code Playgroud)

我试图遍历层次树,并在树的所有起点的单独行中列出它命中的所有节点。这就是样本数据给我的方式。

ind*_*iri 10

你走在正确的道路上,几乎已经做到了。在第二部分的选择中,父列应该来自 cte 而不是 S2 并且在第二部分中连接是向后的(S2.id = p.parentvs S2.parent = p.id)。但就是这样!

create table [table]
(
id int,
parent int
);

insert into [table] values(1,NULL),
    (2,1),
    (3,1),
    (4,2),
    (5,2),
    (6,2),
    (7,3),
    (8,4);


;WITH ctetable(id, parent, depth, path) as 
(
    SELECT S.id, S.parent, 1 AS depth, convert(varchar(100), S.id) AS path
    FROM [table] as S
    UNION ALL
    SELECT S2.id, p.parent, p.depth + 1 AS depth, convert(varchar(100), (RTRIM(p.path) +'->'+ convert(varchar(100), S2.id)))
    FROM ctetable AS p JOIN [table] as S2 on S2.parent = p.id
    WHERE p.parent is not null
)
SELECT * FROM ctetable ORDER BY id, parent;
Run Code Online (Sandbox Code Playgroud)