SQL递归查询如何不进入无限循环?

时间:2016-11-30 18:48:30

标签: sql recursion

有人可以解释一下为什么下面的查询不会遇到无限循环吗?也许,来自PostgreSQL网站的这个例子将有所帮助:

WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION
    SELECT n+1 FROM t WHERE n < 100
)
SELECT * FROM t;

在SQL中,fromwhere进行评估。那么,如果没有评估where条款,我们是否会不断进入t?

1 个答案:

答案 0 :(得分:2)

“递归”查询中没有“递归” 它应该被称为“迭代”。

供应商之间存在一些差异,但基本概念是相同的:

  1. 锚点部分(不引用“递归”查询名称的部分)会创建初始集。

  2. 迭代部分(引用“递归”查询名称的部分)使用最后一个集来创建一个现在成为最后一个集的新集,依此类推。
    当它变为空集时停止。

  3. 这是一个无休止的询问:

    with recursive t as (select 1 union all select 1 from t) 
    select count(*) from t
    

    OP示例的说明

    Initial set created by the anchor part, `VALUES (1)`: 
    1 record, n=1
    
    Sets created by the iterative part, `SELECT n+1 FROM t WHERE n < 100`:
    1 record, n=2 (the initial set has 1 record with n=1 so `SELECT n+1 from t` returns 2)
    1 record, n=3 
    1 record, n=4
    1 record, n=5
    .
    .
    .
    1 record, n=99
    1 record, n=100 
    
    When n=100 the WHERE condition `WHERE n < 100` causes an empty set to be created 
    and the iteration stops.
    

    考虑迭代查询的一种方法:

    with        t0 as (select ...)
               ,t1 as (select ... t0 ...)
               ,t2 as (select ... t1 ...)
               ,t3 as (select ... t2 ...)
                .
                .
                .
    
                select * from t0
    union all   select * from t1
    union all   select * from t2
    union all   select * from t3
    union all   ...
    

    t0是CTE,在其他CTE中没有依赖关系 t1是依赖于t0的CTE t2是依赖于t1的CTE(并且只有t1!) t3是依赖于t2的CTE(并且只有t2!) 等。

    t1,t2,t3等用相同的查询声明,仅在它们的依赖项中有所不同。