DECLARE @Table AS TABLE (Child INT, Parent INT)
INSERT INTO @Table VALUES (1,3),(2,1),(7,5)
;WITH cteRecursive AS (
SELECT
OriginalChild = Child
,Child
,Parent
,Level = 0
FROM
@Table
WHERE
Child = 2
UNION ALL
SELECT
c.OriginalChild
,t.Child
,t.Parent
,Level + 1
FROM
cteRecursive c
INNER JOIN @Table t
ON c.Parent = t.Child
)
SELECT TOP 1 TopAncestor = Parent
FROM
cteRecursive
ORDER BY
Level DESC
使用递归cte来回避树,直到你不能。跟踪递归级别,然后采用递归父级的最后一级,并且您拥有顶级祖先。
只因为我写了它,如果你想找到每个孩子的最高祖先,我会加入。这个概念仍然相同,但您需要引入row_number()
来查找递归的最后一个级别。
DECLARE @Table AS TABLE (Child INT, Parent INT)
INSERT INTO @Table VALUES (1,3),(2,1),(7,5),(5,9)
;WITH cteRecursive AS (
SELECT
OriginalChild = Child
,Child
,Parent
,Level = 0
FROM
@Table
UNION ALL
SELECT
c.OriginalChild
,t.Child
,t.Parent
,Level + 1
FROM
cteRecursive c
INNER JOIN @Table t
ON c.Parent = t.Child
)
, cteTopAncestorRowNum AS (
SELECT
*
,TopAncestorRowNum = ROW_NUMBER() OVER (PARTITION BY OriginalChild ORDER BY Level DESC)
FROM
cteRecursive
)
SELECT
Child = OriginalChild
,TopMostAncestor = Parent
FROM
cteTopAncestorRowNum
WHERE
TopAncestorRowNum = 1
你总是想要返回gradparent还是要返回最顶端的祖先?因为前者可以用2个连接完成,而后者将采用递归等技术。顶级父母也总是在表中有记录吗? – Matt
@Matt谢谢你澄清......最顶级的祖先就是我所追求的,没有最顶级的祖先不会有父母。我会更新我的问题。 – 40Alpha
我得到他们将不会有父母,但我想知道是否仍然有故事中的记录,例如子3,父NULL? – Matt