我无法理解递归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
?
如果是这种情况,最终结果应该有许多重复值,例如2
和UNION ALL
。
文档的相关部分说明了以下关于&#34;工作表&#34;和一个&#34;中间表&#34;,虽然描述性不够清楚我:
1.评估非递归术语。 ...在递归查询的结果中包括所有剩余行,并将它们放在临时行中 工作台。
2.只要工作台不为空,请重复以下步骤:
一个。评估递归项,替换当前的内容 递归自引用的工作表。 ......包括所有 递归查询结果中的剩余行,也放置 他们在临时中间表中。
湾用内容替换工作表的内容 中间表,然后清空中间表。
我的问题是:
任何人都可以通过上面的简单示例逐步解释发生了什么吗?
另外,我试图从编程角度理解这种递归CTE。任何人都可以在上面的CTE中勾勒出算法的骨架来生成序列吗?
答案 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
评估,具有讽刺意味的是迭代!
在您的示例中,1
和SELECT
之间的两个集合(n
值的静态集合和2
设置为5
)仅评估一次,最重要的是,采用自上而下的方法。
更重要的是,奇怪(在命名中)来自SQL标准委员会,我怀疑你有很多腿部空间,但要理解“迭代”#39;评价的性质,尽管措辞为“递归”。