合并的父子行 - SQL

Combine Parent-Child Rows - TSQL

我正在尝试从具有父子层次结构的 table 中提取 flatten/combine 行。我试图确定每个 'link' 的开始和结束 - 所以如果 a 是 linked 到 b, b linked 到 c, 然后 c 是 linked 到 d,我希望输出到 link ad

我尽量避免使用带有循环的过程,因此非常感谢任何建议!

原始数据集和需要的输出如下:

personID | form    | linkedform   
---------|---------|---------
    1    |    a    |   b
    1    |    b    |   c
    1    |    c    |   d
    1    |    d    |   NULL
    2    |    e    |   f
    2    |    f    |   g
    2    |    g    |   NULL
    2    |    h    |   i
    2    |    i    |   NULL
    3    |    j    |   NULL
    3    |    k    |   l
    3    |    l    |   NULL

期望的输出:

personID | form    | linkedform   
---------|---------|---------
    1    |    a    |   d
    2    |    e    |   g
    2    |    h    |   i
    3    |    j    |   NULL
    3    |    k    |   l

每个personID可以有多个link,一个link可以只有一种或多种形式。

-- use a recursive cte to build the hierarchy
-- start with [linkedform] = null and work your way up
;WITH cte AS 
(
    SELECT  *, [form] AS [root],
            1 AS [Level]
    FROM    Table1
    WHERE   [linkedform] IS NULL
    UNION ALL  
    SELECT  t1.*,
            [root],
            [Level] + 1
    FROM    Table1 t1
    JOIN    cte ON cte.form = t1.linkedform
)
-- level 1 will be the last element, use row_number to get the first element
-- join the two together based on last and first level, that have the same personid and root ([linkedform] = null)
SELECT  cte.personId,
        cte2.form, 
        cte.form
FROM    cte
        JOIN (  SELECT  *, 
                        ROW_NUMBER() OVER (PARTITION BY personId, [root] ORDER BY Level DESC) Rn 
                FROM    cte) cte2 
            ON cte2.Rn = cte.Level 
                AND cte2.personId = cte.personId
                AND cte2.root = cte.root
WHERE   cte.[Level] = 1
ORDER BY cte.personId, cte2.form