【问题标题】:T-SQL Why recursion dont stop?T-SQL 为什么递归不会停止?
【发布时间】:2016-07-11 19:53:33
【问题描述】:
为什么这个递归不会停止?
DECLARE @T TABLE( id INT )
INSERT INTO @T( id ) VALUES (1), (2)
WITH cte AS(
SELECT id, 1 a FROM @T WHERE id = 1
UNION ALL
SELECT T.id, O.id
FROM @T T outer apply( SELECT * FROM cte WHERE cte.id = T.id ) O
WHERE O.id IS NULL
)
SELECT * FROM cte
如果我使用临时表 #cte 并将重复递归部分 - 经过一些迭代后将是 0 条记录...
【问题讨论】:
标签:
sql
sql-server
recursion
common-table-expression
【解决方案1】:
我会将此添加为评论,但我没有足够的声誉这样做。
递归 CTE 的锚成员定义是正确的。但不是递归成员定义。因为查询总会返回一条记录
SELECT T.id, O.id
FROM @T T outer apply( SELECT * FROM cte WHERE cte.id = T.id ) O
WHERE O.id IS NULL
递归永远持续下去。
尝试 WHERE O.id IS NOT NULL
欲了解更多信息:Recursive CTEs MSDN
【解决方案2】:
你从一行开始:
SELECT id, 1 a FROM @T WHERE id = 1
1 1
第一次递归返回两行(基于CROSS APPLY),WHERE 删除其中一行:
SELECT T.id, O.id
FROM @T T outer apply( SELECT * FROM cte WHERE cte.id = T.id ) O
WHERE O.id IS NULL
1 1 -- filtered
2 NULL -- returned and used for next recursion
每个以下递归返回两行:
SELECT T.id, O.id
FROM @T T outer apply( SELECT * FROM cte WHERE cte.id = T.id ) O
WHERE O.id IS NULL
1 NULL -- returned and used for next recursion
2 NULL -- returned and used for next recursion
结果是正确的,可能是你尝试应用的逻辑。
你实际上想做什么?按原样查询是非常没用的......