2

I have this table in SQL Server:

Parent Child 1 2 89 7 2 3 10 5 3 4

I need to build a recursive Stored Procedure that finds the maximum ascendant of any child.

For example: If I want to find the maximum ascendant of 4, it should return 1 because:

4 is the child of 3.

3 is the child of 2.

2 is the child of 1.

So I can find the ultimate parent.

danywarner
  • 928
  • 2
  • 15
  • 28

2 Answers2

6

A perfect job for recursive CTE:

;WITH
    cte1 AS
    (   -- Recursively build the relationship tree
        SELECT      Parent
                ,   Child
                ,   AscendentLevel = 1
        FROM        my_table
        UNION ALL
        SELECT      t.Parent
                ,   cte1.Child
                ,   AscendentLevel = cte1.AscendentLevel + 1
        FROM        cte1
        INNER JOIN  my_table    t   ON t.Child = cte1.Parent
    ),
    cte2 AS
    (   -- Now find the ultimate parent
        SELECT      Parent
                ,   Child
                ,   rn = ROW_NUMBER() OVER (PARTITION BY Child ORDER BY AscendentLevel DESC)
        FROM        cte1
    )

SELECT  *
FROM    cte2
WHERE   rn = 1
OPTION  (MAXRECURSION 0)
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • 1
    +1 for an excellent answer. I was working on wrapping up my answer, but I saw your response and found it better. Here is a SQL Fiddle for this if you would like to add it to your answer. http://www.sqlfiddle.com/#!3/3bf43/1/0 – FutbolFan Aug 11 '15 at 14:09
  • Thank you Zoff Dino. Great answer! – danywarner Aug 11 '15 at 14:24
0
WITH CTE_myTable AS (
    SELECT        Id, ParentId, NULL As RootParent, 1 As Lvl
    FROM            dbo.myTable
    UNION ALL
    SELECT        a.id, b.ParentId, a.ParentId As RootParent, Lvl + 1
    FROM            CTE_myTable AS a INNER JOIN
                                               dbo.myTable AS b ON a.ParentId = b.Id
)
, CTE_myTable_RN AS  (
    SELECT Id, RootParent, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Lvl DESC) RN
    FROM CTE_myTable
)
, JoinParentChild As (
    SELECT Id, ISNULL(RootParent, Id) As RootParent
    FROM CTE_myTable_RN
    WHERE RN = 1
)

SELECT  TOP(100) PERCENT JoinParentChild.Id, JoinParentChild.RootParent
FROM JoinParentChild 
ORDER BY JoinParentChild.Id
Zanyar Jalal
  • 1,407
  • 12
  • 29