我认为我已经掌握了递归CTE的格式,可以编写一个,但我仍然感到非常沮丧,因为我无法手动处理它(假装成SQL引擎自己并用笔和纸达到结果集)。我找到了这个, 它接近我想要的,但不够详细。我没有问题追踪C ++递归函数并理解它如何运行 - 但对于SQL,我不明白引擎为什么或如何知道何时停止。锚点和递归块每次都会被调用吗?还是在后面的迭代中跳过锚点?(我怀疑,但我试图表达我对它似乎跳来跳去的方式感到困惑。)如果每次都调用锚点,那么锚点如何不会出现多次在最终结果中?我希望有人能够逐行分解发生了什么以及随着结果集累积,“在内存中”的内容。
我已经借用了这个页面的示例, 因为它似乎是最容易理解的。
DECLARE @tbl TABLE (
Id INT
, [Name] VARCHAR(20)
, ParentId INT
)
INSERT INTO @tbl( Id, Name, ParentId )
VALUES
(1, 'Europe', NULL)
,(2, 'Asia', NULL)
,(3, 'Germany', 1)
,(4, 'UK', 1)
,(5, 'China', 2)
,(6, 'India', 2)
,(7, 'Scotland', 4)
,(8, 'Edinburgh', 7)
,(9, 'Leith', 8)
;
WITH abcd
AS (
-- anchor
SELECT id, Name, ParentID,
CAST(Name AS VARCHAR(1000)) AS Path
FROM @tbl
WHERE ParentId IS NULL
UNION ALL
--recursive member
SELECT t.id, t.Name, t.ParentID,
CAST((a.path + '/' + t.Name) AS VARCHAR(1000)) AS "Path"
FROM @tbl AS t
JOIN abcd AS a
ON t.ParentId = a.id
)
SELECT * FROM abcd