【问题标题】: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
    

    结果是正确的,可能是你尝试应用的逻辑。

    你实际上想做什么?按原样查询是非常没用的......

    【讨论】:

      猜你喜欢
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      相关资源
      最近更新 更多