【问题标题】:Understanding steps of recursive CTE了解递归 CTE 的步骤
【发布时间】:2016-03-14 03:44:02
【问题描述】:

就中间步骤和沿途涉及的工作/临时表而言,我无法理解递归 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

文档的相关部分对“工作表”和“中间表”进行了以下说明,尽管对我来说描述性不够清楚:

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

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

一个。计算递归项,代入当前内容 递归自引用的工作表。 ... 包括所有 递归查询结果中的剩余行,并且还放置 它们在一个临时中间表中。

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

我的问题是:

谁能逐步解释上面的简单示例发生了什么?

另外,我试图从编程的角度来理解这个递归 CTE。谁能勾勒出上述 CTE 中生成序列的算法的骨架?

【问题讨论】:

  • 正是我想知道的东西谢谢!!

标签: postgresql recursion common-table-expression


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    在您的示例中,这两个集合(具有1 值的静态集合和具有n25 之间的SELECT 集合)仅被评估一次,最重要的是,采用自上而下的方法。

    更何况,奇怪的是(命名)来自 SQL 标准委员会,我怀疑你有很大的余地,但要理解评估的“迭代”性质,尽管措辞为“递归”。

    【讨论】:

    • 定义是递归的,因为 CTE 引用它自己。实现可能是迭代的,也可能不是。
    • 我想已经意识到SELF REFERENTIAL 不是一个好关键字。
    • @ypercubeᵀᴹ 但这就是问题所在:CTE 并不真正引用自身,而只是引用在上一次迭代中创建的临时表。在第 n-2 次迭代时你永远看不到结果...它不是递归的!
    • @autra 定义是递归的,不知道怎么写。。你指的是实现吗?
    • @ypercubeᵀᴹ 不,我指的是自我引用在我看来并不是真正的自我引用......
    猜你喜欢
    • 2018-02-03
    • 2012-12-08
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多