Reputation: 1689
Max_ID Second_Max_ID Cumulative_ID
173 97 ,97
174 173 ,97,173
... ... ...
I need to write a query to compute the cumulative id. Can someone help? It's a temporary table with 3 columns(Max_ID,Second_Max_ID,Cumulative_ID) where I have just Max_ID and Second_Max_ID value in table and I need to compute Cumulative_ID for each row in the same temporary table.
I used query provided by shnugo and modified the query as below -
DECLARE @mockup TABLE(Max_ID INT,Second_Max_ID INT);
INSERT INTO @mockup VALUES
(173 , 97 )
,(174 , 173 );
WITH recCTE AS
(
SELECT Max_ID
,Second_Max_ID
,CAST(Second_Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
FROM @mockup --WHERE Second_Max_ID IS NULL
UNION ALL
SELECT m.Max_ID
,m.Second_Max_ID
,r.Cumulative_ID+','+ cast(m.Second_Max_ID as varchar(max))
FROM @mockup m
INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * FROM recCTE;
Now getting result like -
Max_ID Second_Max_ID Cumulative_ID
173 97 97
174 173 173
174 173 97,173
How can I remove the second row from above result?
Upvotes: 0
Views: 833
Reputation: 67311
You can try this:
DECLARE @mockup TABLE(Max_ID INT,Second_Max_ID INT);
INSERT INTO @mockup VALUES
(97 ,NULL )
,(173 , 97 )
,(174 , 173 )
,(175 , 174 );
WITH recCTE AS
(
SELECT Max_ID
,Second_Max_ID
,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
FROM @mockup WHERE Second_Max_ID IS NULL
UNION ALL
SELECT m.Max_ID
,m.Second_Max_ID
,CONCAT(r.Cumulative_ID,',',m.Max_ID)
FROM @mockup m
INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * FROM recCTE;
The idea is a recursive CTE (rather an iterative approach). You start of with the one row with no parent (the Second_Max_ID IS NULL
).
This traverses down the list (a hidden RBAR) and does the concatenation on the fly.
You've tagged with v2008 and v2012. If CONCAT()
does not work for you, you can easily use simple +
with the needed convert to varchar
.
In this version I'll add a counter for the hierarchy depth:
WITH recCTE AS
(
SELECT Max_ID
,Second_Max_ID
,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
,1 AS HierarchyLevel
FROM @mockup WHERE Second_Max_ID IS NULL
UNION ALL
SELECT m.Max_ID
,m.Second_Max_ID
,CONCAT(r.Cumulative_ID,',',m.Max_ID)
,r.HierarchyLevel+1
FROM @mockup m
INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT *
FROM recCTE;
You can use
WHERE
to filter for a special levelORDER BY HierachyLevel DESC
to get the last element (the one with the longest path).Hope this helps!
Upvotes: 1