进行类似查询的递归 CTE,但对于许多记录

PAP*_*PAP 4 sql-server cte recursive

我有一个带有层次结构的表(带有递归 parentID 列),对于一个记录,我知道如何使用以下代码获取最后一个父记录:

declare @Id integer

;WITH CTE AS
(
    SELECT  a.[Id],
            a.[ParentId]
    FROM    [Area] a WITH (NOLOCK)
    where a.[Id] = @Id 

    UNION ALL

    SELECT  a.[Id],
            a.[ParentId]
    FROM [Area] a WITH (NOLOCK)
    INNER JOIN CTE cte ON cte.[ParentId] = a.[Id]
)

SELECT top 1 a.[Id]
FROM CTE a
WHERE a.ParentId is null
Run Code Online (Sandbox Code Playgroud)

只要我使用一个 id 就可以工作,这里是 @Id。

但是我找不到一种方法来做同样的事情,但对于 Id 列表,不使用游标,因为 CTE 似乎只有在您处理一条记录时才可以。

有人能指出我正确的方向吗?

非常感谢

Pau*_*ite 5

假设原来的表设计有点像这样:

CREATE TABLE dbo.Area
(
    RowID integer PRIMARY KEY,
    GroupID  integer NOT NULL,
    ParentID integer NULL,
);
Run Code Online (Sandbox Code Playgroud)

样本数据:

INSERT dbo.Area
    (RowID, GroupID, ParentID)
VALUES 
    (1, 1, NULL), -- Root
    (2, 1, 1),
    (3, 1, 2),
    (4, 2, NULL), -- Root
    (5, 2, 4),
    (6, 2, 5),
    (7, 2, 6);
Run Code Online (Sandbox Code Playgroud)

以下递归 CTE 查询查找RowID锚中给定列表的根:

WITH R AS
(
    SELECT
        A.RowID,
        A.RowID AS OriginalRowID,
        A.ParentID
    FROM dbo.Area AS A
    WHERE
        A.RowID IN (3, 7)

    UNION ALL

    SELECT
        A.RowID,
        R.OriginalRowID,
        A.ParentID
    FROM dbo.Area AS A
    JOIN R
        ON R.ParentID = A.RowID
)
SELECT
    R.OriginalRowID,
    R.RowID
FROM R
WHERE
    R.ParentID IS NULL
ORDER BY
    R.OriginalRowID
OPTION (MAXRECURSION 0);
Run Code Online (Sandbox Code Playgroud)

输出显示每个提供的RowID和该组的根:

输出

  • 是的。即使层次结构允许一个节点的多个父节点(它会找到所选/锚定节点的所有根祖先),该查询也能工作。 (2认同)