sql-server - cte递归部分仅返回一行

标签 sql-server common-table-expression recursive-query

如果我的 CTE 的递归部分没有联接,每次递归只能得到一行,这是为什么?

在 SQL Server 2016 和 Azure SQL 数据库上测试的代码:

DECLARE @Number TABLE (Number INT);

INSERT INTO @Number (Number)
VALUES (1), (2);

;WITH _cte AS 
(
     SELECT Number
     FROM @Number
     UNION ALL
     SELECT _cte.Number
     FROM _cte
)
SELECT *
FROM _cte
OPTION (MAXRECURSION 2); -- just call recursive part twice to see the issue

在结果中,我在每个递归/深度中得到数字2

我希望当前行在每次递归中重复,因此行数呈指数增长

预期输出

Number
--------------------    
1   -- from anchor
2   
1   -- first recursion
2   
1   -- second recursion
2   
1   
2   

实际输出:

Number
--------------------    
1   -- from anchor
2   
2   -- first recursion  
2   -- second recursion

最佳答案

从一些测试来看,SQL 递归似乎是从初始查询返回的最后一行开始深度优先发生的。一旦达到 MAXRECURSION ,查询就会因错误而终止(例如,语句终止。在语句完成之前最大递归 2 已用尽。)并返回任何结果它在错误发生之前到达。您可以通过在插入语句中插入 2,1 而不是 1,2 或通过在 @Number 表中插入 1,2,3 来验证这一点。如果将 1,2,3 插入到 @Number 中,返回的结果将为

1  -- From anchor
2  -- From anchor
3  -- From anchor
3  -- 1st recursion from last row of anchor query
3  -- Recursion from the row from the line above this (2nd recursion)
-- Query terminates after MAXRECURSION reached on an item and does not attempt recursion on 1 or 2

通常,在使用递归时,您可以使用 where 语句中的某些条件或连接中的 on 条件将 CTE 与其本身或其他表连接起来,这些条件将根据可用数据限制递归(而不仅仅是通过相同的元素)。例如(使用与您的问题相同的 @Number 表):

DECLARE @Number TABLE (Number INT);

INSERT @Number
(
    Number
)
VALUES (1),
(2);
WITH _cte2
AS
    (SELECT 
        Number
        ,0 as 'RecursionCount'
    FROM
        @Number

    UNION ALL
        SELECT
        Number
        ,RecursionCount + 1
    FROM
        _cte2
    WHERE
        RecursionCount <= 1
    )
SELECT * FROM _cte2 OPTION (MAXRECURSION 2);

在上面的示例中,查询将在 where 语句中限制其自身的递归,并且永远不会达到 MAXRECURSION,因此查询将能够完成。您还会注意到,返回结果的顺序证实了我的怀疑,即递归是从最后一项开始的深度优先:

Number  RecursionCount
1       0
2       0
2       1
2       2
1       1
1       2

关于sql-server - cte递归部分仅返回一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53228439/

相关文章:

sql - 将数据修改 CTE 中的 INSERT 语句与 CASE 表达式组合

sql-server - 递归 CTE 中的 TSQL GROUP BY

SQL递归CTE查询错误 'invalid column name - level'

mysql - 通过父id和mysql中的where子句获取所有子项

sql - Oracle中的简单递归查询

postgresql:有序结果

sql-server - 执行 SSIS 包给出 System.IO.IOException

sql - MSSQLSRV - 过滤掉重复行的结果

sql-server - 使用 sp_executesql proc 创建 SQL 登录

sql-server - SQL Server : How to limit CTE recursion to rows just recursivly added?