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