Yesterday's Interview I was asked a interesting question that how to find the highest ParentID for each row.
I couldn't answer this question that time, but I found the solution online but I still cannot understand how this query works...
Can anyone explain to me how Recursive CTE works in detail? Thanks
I post the sample question and solution I come up with at the button
=================================================================
Create table dbo.##Test001 (ID int, Name varchar(100), ParentID int)
Insert into ##Test001 values (1, 'AA', null), (2, 'BB', 1), (3, 'CC', 2), (4, 'DD', 3)
,(5, 'AAA', null), (6, 'BBB', 5), (7, 'CCC', 6), (8, 'DDD', 7)
;WITH c AS (
SELECT id, parentid, id AS topParentID FROM ##Test001
WHERE ParentID is null
UNION ALL
SELECT T.id, T.parentid, c.topparentid FROM ##Test001 AS T
INNER JOIN c
ON T.parentid = c.id
WHERE T.id <> T.parentid
)
SELECT id, topparentid FROM c
ORDER BY id
It might help to remind yourself about recursion using a function.
-- pseudo code
void numberFunction(int i) {
Print i
increment i
if(i<10) {
numberFunction(i);
}
}
Or, even better a math function that you can do by hand.
Fact (n) = n * fact (n-1) for n > 0
The structure of the recursive common table expression (CTE) is:
UNION ALL
Notice in the math/pseudo code function, we either increment or decrement a variable and check for the exit state.
In this query the increment / decrement functionality is in the recursive query when T.id is returned for the matched T.parentid
The exit state for this query is when the recursive query returns an empty set.
WITH c AS
(
SELECT
id, parentid, id AS topParentID
FROM
#Test001
WHERE
ParentID is null
UNION ALL
SELECT
T.id, T.parentid, c.topparentid
FROM
#Test001 AS T
INNER JOIN
c ON T.parentid = c.id
WHERE
T.id <> T.parentid
)
SELECT id, topparentid
FROM c
ORDER BY id
The output of the anchor establishes the topmost parent and serves as the the input to the recursive query.
id parentid topParentID
1 NULL 1
5 NULL 5
This output is then joined with the temp table #Test001 T on T.parentid = c.id.
ID Name ParentID
1 AA NULL
2 BB 1
3 CC 2
4 DD 3
5 AAA NULL
6 BBB 5
7 CCC 6
8 DDD 7
SELECT T.id, T.parentid, c.topparentid
FROM #Test001 AS T
INNER JOIN c ON T.parentid = c.id
T.id T.parentid c.topparentid
2 1 1
6 5 5
You can continue the process for the remaining id/parent id combinations.
UNION ALL combines all the results of both the anchor query and all recursive queries. UNION ALL can be used with queries with same number of parameters and similar types.
Source: Recursive Queries Using CTE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.