昨天的访谈我被问到一个有趣的问题,即如何找到最高的 每行的ParentID。
那时候我无法回答这个问题,但我在网上找到了解决方案,但我仍然无法理解这个查询的工作原理......
任何人都可以向我解释递归CTE的详细信息吗?感谢
我在按钮
上发布了我提出的示例问题和解决方案=============================================== ==================
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
答案 0 :(得分:2)
使用函数提醒自己可能会有所帮助。
-- pseudo code
void numberFunction(int i) {
Print i
increment i
if(i<10) {
numberFunction(i);
}
}
或者,你可以手工完成更好的数学功能。
Fact (n) = n * fact (n-1) for n > 0
递归公用表表达式(CTE)的结构是:
UNION ALL
注意在math / pseudo代码函数中,我们要么递增或递减变量,要检查退出状态。
在此查询中,当为匹配的T.parentid返回T.id时,递增/递减功能在递归查询中
此查询的退出状态是递归查询返回空集。
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
锚的输出建立最顶层的父级,并作为递归查询的输入。
id parentid topParentID
1 NULL 1
5 NULL 5
然后将此输出与T.parentid = c.id上的临时表#Test001 T连接。
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
您可以继续执行剩余ID /父ID组合的过程。
UNION ALL结合了锚点查询和所有递归查询的所有结果。 UNION ALL可以与具有相同数量的参数和类似类型的查询一起使用。