CTE 执行顺序

Seb*_*idz 5 postgresql common-table-expression

在以下 CTE 声明中:

CREATE TABLE test_table (Field1 INTEGER, Field2 INTEGER);
CREATE TABLE test_table2 (Field1 INTEGER, Field2 INTEGER);

WITH table_stage1(fld1, fld2) AS
    (SELECT Field1, Field2 from test_table1)
, table_stage2 AS 
    (SELECT fld1, fld2 FROM table_stage1 GROUP BY fld1, fld2)
, table_stage3 AS 
    (SELECT fld1 FROM table_stage1 GROUP BY fld1)
INSERT INTO test_table2(Field1, Field2)
    SELECT t1.fld1, t2.fld2
        FROM table_stage2 t1
        JOIN table_stage3 t2
    ON t1.fld1 = t2.fld1;
Run Code Online (Sandbox Code Playgroud)

我可以假设以下查询执行顺序:

  1. SELECT 里面 WITH 语句
  2. 并发执行SELECTinsidetable_stage2table_stage3
  3. INSERT INTO等待,直到执行table_stage2table_stage3完成

这个问题与特定的(提出的)陈述无关。

我想知道通过从命名段中选择是否可以保证当前语句将在特定命名段之后执行。Meybe 什么是significat 有许多选择语句后跟一个写入 CTE 连接来自先前段的结果

我们可以阅读的 PostgeSQL文档

WITH 中的子语句彼此并发执行,并与主查询同时执行。因此,在 WITH 中使用数据修改语句时,指定更新实际发生的顺序是不可预测的。

我正在研究 PostgreSQL 9.6

Ren*_*nzo 5

您引用的文档部分是指执行多个数据修改语句(使用数据修改语句......顺序是不可预测的)。但是如果在其中一个语句中使用了前一个语句的名称,这意味着当前语句引用了所有元组了前一个返回的。

因此,在您的示例中,与table_stage2和相关的语句table_stage3可以并行执行,但使用 table_stage1 返回的所有元组,而最终insert将使用前两个语句返回的所有元组执行(因此通过使用所有元组由前三个语句产生)。

注意:“B 使用了 A 返回的所有元组”并不一定等同于:“B 在 A 之后执行”:优化器实际上可以转换 B,因此不需要执行 A。它只是一个语义定义,并且与实际实现无关。