CTE执行订单

时间:2017-12-03 20:14:55

标签: 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;

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

    WITH statemt 里面的
  1. SELECT
  2. SELECTtable_stage2段内同时执行table_stage3
  3. INSERT INTO等待table_stage2执行,table_stage3完成
  4. 此问题与特定(呈现)声明无关。

    我想知道从命名段中选择是否有保证当前语句将在特定命名段之后执行。 Meybe有意义的是有一些选择语句,这些语句包含一个连接前一段结果的写入CTE

    我们可以阅读的PostgeSQL documentations

      

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

    我正在研究PostgreSQL 9.6

1 个答案:

答案 0 :(得分:3)

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

因此,在您的示例中,相对于table_stage2table_stage3的语句可以并行执行,但使用table_stage1返回的所有元组,而最终的insert将由使用前两个语句返回的所有元组(因此使用前三个语句生成的所有元组)。

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