假设我有一个递归表(例如,有经理的员工)和一个大小为 0..n 的id列表。如何找到这些ID的最低公共父级?

例如,如果我的表格如下:

Id | ParentId
---|---------
 1 |     NULL
 2 |        1
 3 |        1
 4 |        2
 5 |        2
 6 |        3
 7 |        3
 8 |        7

然后以下几组ID导致以下结果(第一个是角落情况):

[]      => 1 (or NULL, doesn't really matter)
[1]     => 1
[2]     => 2
[1,8]   => 1
[4,5]   => 2
[4,6]   => 1
[6,7,8] => 3

怎么做?

编辑:请注意,在所有情况下,父级都不是正确的术语。它是树中所有路径中的最低公共节点。最低公共节点也可以是节点本身(例如,在 [1,8] => 1 的情况下,节点 1 不是节点 1 但节点 1 本身。)

亲切的问候, 罗纳德

有帮助吗?

解决方案 2

在从Marc的回答中做出一些正确的思考和一些提示之后(谢谢),我自己提出了另一个解决方案:

DECLARE @parentChild TABLE (Id INT NOT NULL, ParentId INT NULL);
INSERT INTO @parentChild VALUES (1, NULL);
INSERT INTO @parentChild VALUES (2, 1);
INSERT INTO @parentChild VALUES (3, 1);
INSERT INTO @parentChild VALUES (4, 2);
INSERT INTO @parentChild VALUES (5, 2);
INSERT INTO @parentChild VALUES (6, 3);
INSERT INTO @parentChild VALUES (7, 3);
INSERT INTO @parentChild VALUES (8, 7);

DECLARE @ids TABLE (Id INT NOT NULL);
INSERT INTO @ids VALUES (6);
INSERT INTO @ids VALUES (7);
INSERT INTO @ids VALUES (8);

DECLARE @count INT;
SELECT @count = COUNT(1) FROM @ids;

WITH Nodes(Id, ParentId, Depth) AS
(
    -- Start from every node in the @ids collection.
    SELECT pc.Id , pc.ParentId , 0 AS DEPTH
    FROM @parentChild pc
    JOIN @ids i ON pc.Id = i.Id

    UNION ALL

    -- Recursively find parent nodes for each starting node.
    SELECT pc.Id , pc.ParentId , n.Depth - 1
    FROM @parentChild pc
    JOIN Nodes n ON pc.Id = n.ParentId
)
SELECT n.Id
FROM Nodes n
GROUP BY n.Id
HAVING COUNT(n.Id) = @count
ORDER BY MIN(n.Depth) DESC

它现在返回从最低公共父节点到根节点的整个路径,但这是向

内容是在创意共享下获得许可的。

如果您发现侵犯版权,可以通过 info@generacodice.com 要求删除内容。

scroll top