Reputation: 303
I would like to get the Top most Ancestor (Root) of the hierarchy from any level of data. The following is my table.
CREATE TABLE #SMGROUP (ID INT NOT NULL, GRP NVARCHAR(40), GRPCLASS INT, PARENTGRP NVARCHAR(40), PARENTGRPCLASS INT)
INSERT INTO #SMGROUP VALUES (1, 'A', 1, NULL,NULL)
INSERT INTO #SMGROUP VALUES (1, 'B', 1, NULL,NULL)
INSERT INTO #SMGROUP VALUES (1, 'C', 1, NULL,NULL)
INSERT INTO #SMGROUP VALUES (1, 'A.1', 2, 'A',1)
INSERT INTO #SMGROUP VALUES (1, 'A.2', 2, 'A',1)
INSERT INTO #SMGROUP VALUES (1, 'A.3', 2, 'A',1)
INSERT INTO #SMGROUP VALUES (1, 'B.1', 2, 'B',1)
INSERT INTO #SMGROUP VALUES (1, 'B.2', 2, 'B',1)
INSERT INTO #SMGROUP VALUES (1, 'A.3.3', 3, 'A.3',2)
INSERT INTO #SMGROUP VALUES (1, 'A.3.3.3', 4, 'A.3.3',3)
INSERT INTO #SMGROUP VALUES (1, 'A.3.3.3.1', 5, 'A.3.3.3',4)
INSERT INTO #SMGROUP VALUES (1, 'B.1.2', 3, 'B.1',2)
INSERT INTO #SMGROUP VALUES (1, 'B.2.1', 3, 'B.2', 2)
SELECT * FROM #SMGROUP
I Would like to have the value of - 'A' if I provide 'A.1' as input, also the return value would be 'A' if I provide 'A.3.3' as input. Also the return would be 'A' if the parameter is 'A.3.3.3.1'
I have written some thing like this, but I am not sure how to continue after this.
;WITH items AS (
SELECT G.GRP ,CAST('' AS NVARCHAR(30)) AS ParentGroup,
0 AS Level
FROM #SMGROUP G
WHERE G.PARENTGRP IS NULL
UNION ALL
SELECT G.GRP, CAST(G.PARENTGRP AS NVARCHAR(30)) AS ParentGroup
, Level + 1
FROM #SMGROUP G
INNER JOIN items itms ON itms.GRP = G.PARENTGRP
)
SELECT * FROM items
Upvotes: 0
Views: 787
Reputation: 82474
You are on the right direction, you just need one last push.
Instead of using a "standard" recursive cte that traverse from root to leaf nodes, you "reverse" the process and traverse from the input node back to the root.
Then it's simply a top 1
with level desc
in the order by
clause:
DECLARE @GRP NVARCHAR(40) = 'A.3.3.3.1';
WITH items AS (
SELECT G.GRP,
ISNULL(G.PARENTGRP, '') AS ParentGroup,
0 AS Level
FROM #SMGROUP G
WHERE G.GRP = @GRP
UNION ALL
SELECT G.GRP,
G.PARENTGRP,
Level + 1
FROM #SMGROUP G
INNER JOIN items itms
ON itms.ParentGroup = G.GRP
)
SELECT TOP 1 Grp
FROM items
ORDER BY Level DESC
Upvotes: 1