PostgreSQL嵌套CTE和UNION

Ada*_*ler 20 sql postgresql union common-table-expression

我正在尝试使用PostgreSQL 9.1.3学习SQL.我想了解一些让我觉得不一致的行为.以机智:

这有效:

WITH innermost AS (SELECT 2)
SELECT * FROM innermost
UNION SELECT 3;
Run Code Online (Sandbox Code Playgroud)

我明白了:

 ?column? 
----------
        2
        3
Run Code Online (Sandbox Code Playgroud)

这有效:

WITH outmost AS (
        (WITH innermost AS (SELECT 2)
         SELECT * FROM innermost)
)                                
SELECT * FROM outmost;
Run Code Online (Sandbox Code Playgroud)

结果:

?column? 
----------
        2
Run Code Online (Sandbox Code Playgroud)

这也有效:

WITH outmost AS (
  SELECT 1
  UNION (WITH innermost AS (SELECT 2)
         SELECT * FROM innermost)
)
SELECT * FROM outmost;
Run Code Online (Sandbox Code Playgroud)

我明白了:

 ?column? 
----------
        1
        2
Run Code Online (Sandbox Code Playgroud)

但是,这并不能正常工作:

WITH outmost AS (
  SELECT 1
  UNION (WITH innermost as (SELECT 2)
         SELECT * FROM innermost
         UNION SELECT 3)
)
SELECT * FROM outmost;
Run Code Online (Sandbox Code Playgroud)

结果:

ERROR:  relation "innermost" does not exist
LINE 4:          SELECT * FROM innermost
Run Code Online (Sandbox Code Playgroud)

按照我的思维方式,要么最后一个应该成功,要么其他一个应该失败.我没有看到这种模式.是否有一些通用规则可以让我预测嵌套CTE和UNION的哪些组合将会或不会起作用?

Ada*_*ler 20

这个谜团得到了解决:我观察到的行为是一个已知的错误.我将相同的原始帖子发送到PostgreSQL特定的列表并得到了这个答案:

这是一个错误:-(.解析分析代码似乎认为WITH只能附加到顶级或设置操作树中的叶级SELECT;但语法遵循SQL标准,不会说这样的东西. WITH被接受,并附加到中间级UNION,它在语法上应该去,然后在解析分析时完全被忽略.将看到修复它.

      regards, tom lane
Run Code Online (Sandbox Code Playgroud)

http://archives.postgresql.org/pgsql-novice/2012-07/msg00113.php

  • 似乎这已经在9.2 beta3中得到修复.我引用了时事通讯:`*修复了设置操作的问题(UNION/INTERSECT/EXCEPT)`. (3认同)
  • 我刚刚安装了9.2beta3,是的,我原来帖子中的非工作命令现在按预期工作.谢谢你的提醒. (2认同)
  • 凉爽的!感谢您追踪此事!你的问题值得更多的赞成。:) 顺便说一句,在这种情况下,我们鼓励您接受您自己的(正确)答案。 (2认同)