了解递归CTE的步骤

时间:2016-03-14 03:44:02

标签: postgresql recursion common-table-expression

我无法理解递归CTE的工作原理,包括中间步骤以及整个过程中涉及的工作/临时表。

稍微调整PostgreSQL Documention的示例:

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

在Postgres(9.5)中运行它,我得到:

 n 
---
 1
 2
 3
 4
 5
(5 rows)

但为什么我们没有获得更多行?例如

    SELECT n+1 FROM t WHERE n < 5

当n = 2时,为什么表t有两行

---
 1
 2

并基于该生成

---
 2
 3

? 如果是这种情况,最终结果应该有许多重复值,例如2UNION ALL

文档的相关部分说明了以下关于&#34;工作表&#34;和一个&#34;中间表&#34;,虽然描述性不够清楚我:

  

1.评估非递归术语。 ...在递归查询的结果中包括所有剩余行,并将它们放在临时行中   工作台。

     

2.只要工作台不为空,请重复以下步骤:

     

一个。评估递归项,替换当前的内容   递归自引用的工作表。 ......包括所有   递归查询结果中的剩余行,也放置   他们在临时中间表中。

     

湾用内容替换工作表的内容   中间表,然后清空中间表。

我的问题是:

任何人都可以通过上面的简单示例逐步解释发生了什么吗?

另外,我试图从编程角度理解这种递归CTE。任何人都可以在上面的CTE中勾勒出算法的骨架来生成序列吗?

2 个答案:

答案 0 :(得分:1)

每次CTE的后半部分运行时,它都会看到上一次运行的结果。因此,初始运行执行上半部分并产生1.第二次运行执行下半部分。它将t视为包含1,因此返回2.第三次运行将t视为包含2(不是1和2,因为它只能看到上一次运行的结果),因此它返回3

第四轮看到3并返回4.

第五轮看到4并返回5.

第六次运行看到5,但WHERE子句排除了它,因此它不返回任何行。不返回任何行是要停止的信号。

所以现在CTE的完整结果是1, 2, 3, 4, 5,这就是CTE看到的外部的所有内容。

答案 1 :(得分:0)

您引用的document中的一个非常重要的陈述清楚地说明了您观察的原因。

  

注意:严格来说,这个过程是迭代而不是递归,但是   RECURSIVE是SQL标准委员会选择的术语。

简而言之,WITH RECURSIVE评估,具有讽刺意味的是迭代

在您的示例中,1SELECT之间的两个集合(n值的静态集合和2设置为5)仅评估一次,最重要的是,采用自上而下的方法。

更重要的是,奇怪(在命名中)来自SQL标准委员会,我怀疑你有很多腿部空间,但要理解“迭代”#39;评价的性质,尽管措辞为“递归”。

相关问题