了解递归 CTE 的步骤
Understanding steps of recursive CTE
我无法理解递归 CTE 的工作原理,就中间步骤和整个过程中涉及的 working/temporary table 而言。
稍微改编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 时,为什么 table t
没有两行
---
1
2
并以此为基础生成
---
2
3
?
如果真是这样,最终结果应该有很多重复值,例如 2
和 UNION ALL
.
文档的相关部分说明了以下关于 "working table" 和 "intermediate table" 的内容,尽管对我来说描述不够清楚:
1.Evaluate the non-recursive term. ... Include all remaining rows in the result of the recursive query, and also place them in a temporary
working table.
2.So long as the working table is not empty, repeat these steps:
a. Evaluate the recursive term, substituting the current contents of
the working table for the recursive self-reference. ... Include all
remaining rows in the result of the recursive query, and also place
them in a temporary intermediate table.
b. Replace the contents of the working table with the contents of
the intermediate table, then empty the intermediate table.
我的问题是:
任何人都可以逐步解释上面的简单示例是怎么回事吗?
此外,我试图从编程的角度理解这个递归 CTE。谁能勾勒出上述 CTE 中生成序列的算法框架?
您引用的 document 中的一个非常重要的陈述清楚地给出了您观察的原因。
Note: Strictly speaking, this process is iteration not recursion, but
RECURSIVE is the terminology chosen by the SQL standards committee.
总之,WITH RECURSIVE
评价,讽刺的是迭代!
在您的示例中,两个集合(具有 1
值的静态集合和 2
和 5
之间具有 n
的 SELECT
集合)仅评估 一次,最重要的是,采用自上而下的方法。
更何况,奇怪的(命名)来自 SQL 标准委员会,我怀疑你有多少腿部空间,但要了解评估的 'iterative' 性质,尽管措辞为 'Recursive'.
每次 CTE 的后半部分 运行 时,它会看到 仅 之前 运行 的结果。所以最初的 运行 执行上半部分并产生 1。第二个 运行 执行下半部分。它认为 t
包含 1,因此它 returns 2。第三个 运行 认为 t
包含 2(不是 1 和 2,因为它只看到结果前一个 运行), 所以它 returns 3.
第四个运行看到3和returns4.
第五个运行看到4和returns5.
第六个 运行 看到 5,但是 WHERE
子句排除了它,因此它 returns 没有行。不返回行是停止的信号。
所以现在 CTE 的完整结果是 1, 2, 3, 4, 5
,这是 CTE 看到的 之外的所有内容。
我无法理解递归 CTE 的工作原理,就中间步骤和整个过程中涉及的 working/temporary table 而言。
稍微改编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 时,为什么 table t
没有两行
---
1
2
并以此为基础生成
---
2
3
?
如果真是这样,最终结果应该有很多重复值,例如 2
和 UNION ALL
.
文档的相关部分说明了以下关于 "working table" 和 "intermediate table" 的内容,尽管对我来说描述不够清楚:
1.Evaluate the non-recursive term. ... Include all remaining rows in the result of the recursive query, and also place them in a temporary working table.
2.So long as the working table is not empty, repeat these steps:
a. Evaluate the recursive term, substituting the current contents of the working table for the recursive self-reference. ... Include all remaining rows in the result of the recursive query, and also place them in a temporary intermediate table.
b. Replace the contents of the working table with the contents of the intermediate table, then empty the intermediate table.
我的问题是:
任何人都可以逐步解释上面的简单示例是怎么回事吗?
此外,我试图从编程的角度理解这个递归 CTE。谁能勾勒出上述 CTE 中生成序列的算法框架?
您引用的 document 中的一个非常重要的陈述清楚地给出了您观察的原因。
Note: Strictly speaking, this process is iteration not recursion, but RECURSIVE is the terminology chosen by the SQL standards committee.
总之,WITH RECURSIVE
评价,讽刺的是迭代!
在您的示例中,两个集合(具有 1
值的静态集合和 2
和 5
之间具有 n
的 SELECT
集合)仅评估 一次,最重要的是,采用自上而下的方法。
更何况,奇怪的(命名)来自 SQL 标准委员会,我怀疑你有多少腿部空间,但要了解评估的 'iterative' 性质,尽管措辞为 'Recursive'.
每次 CTE 的后半部分 运行 时,它会看到 仅 之前 运行 的结果。所以最初的 运行 执行上半部分并产生 1。第二个 运行 执行下半部分。它认为 t
包含 1,因此它 returns 2。第三个 运行 认为 t
包含 2(不是 1 和 2,因为它只看到结果前一个 运行), 所以它 returns 3.
第四个运行看到3和returns4.
第五个运行看到4和returns5.
第六个 运行 看到 5,但是 WHERE
子句排除了它,因此它 returns 没有行。不返回行是停止的信号。
所以现在 CTE 的完整结果是 1, 2, 3, 4, 5
,这是 CTE 看到的 之外的所有内容。