理解递归CTE的步骤

tho*_*hor 5 postgresql recursion common-table-expression

我无法理解递归 CTE 的工作原理,包括中间步骤和沿途涉及的工作/临时表。

稍微改编一下PostgreSQL 文档中的示例:

WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < 5
)
SELECT n FROM t;
Run Code Online (Sandbox Code Playgroud)

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

 n 
---
 1
 2
 3
 4
 5
(5 rows)
Run Code Online (Sandbox Code Playgroud)

但为什么我们没有得到更多的行呢?例如

    SELECT n+1 FROM t WHERE n < 5
Run Code Online (Sandbox Code Playgroud)

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

---
 1
 2
Run Code Online (Sandbox Code Playgroud)

并在此基础上生成

---
 2
 3
Run Code Online (Sandbox Code Playgroud)

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

文档的相关部分介绍了以下有关“工作表”和“中间表”的内容,尽管描述性对我来说还不够清楚:

1.评估非递归项。...将所有剩余行包含在递归查询的结果中,并将它们放入临时工作表中。

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

A。评估递归项,用工作表的当前内容替换递归自引用。...将所有剩余行包含在递归查询的结果中,并将它们放入临时中间表中。

b. 将工作表的内容替换为中间表的内容,然后清空中间表。

我的问题是:

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

另外,我试图从编程的角度理解这个递归 CTE。谁能概述一下上述 CTE 中生成序列的算法的框架吗?

Pau*_*rth 3

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

第四次运行看到 3 并返回 4。

第五次运行看到 4 并返回 5。

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

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