PostgreSQL 中 VALUES 子句的行为

Posted

技术标签:

【中文标题】PostgreSQL 中 VALUES 子句的行为【英文标题】:Behavior of VALUES clause in PostgreSQL 【发布时间】:2019-05-23 16:50:45 【问题描述】:

在 Postgres 中,根据其doc,以下工作:

select 1 as column1, 'one' as column2
union all
select 2, 'two'
union all
select 3, 'three'

然而它的扩展名:

select * from (select 1 as column1, 'one' as column2
union all
select 2, 'two'
union all
select 3, 'three')

导致错误:

同样,虽然这有效(假设 Postgres 创建内部别名?):

values(1,'a'), (2, 'b')

以下会导致错误,需要别名:

select * from (values(1,'a'), (2, 'b'))

并且仅在提供此类别名时才开始工作:

select * from (values(1,'a'), (2, 'b')) t(z,y)

同样的不一致似乎也适用于 SELECT 子句,即:

select 1, 2 

独立工作,但不能作为子选择:

select * from (select 1, 2) 

除非提供别名:

select * from (select 1, 2) t(a, b)

如果在另一个选择中使用某些内部别名,例如 Postgres 在使用那些分句独立?

导致这种设计不一致的原因是什么?

【问题讨论】:

【参考方案1】:

VALUES 与 select 一起使用的语法肯定不同于它在大多数 SQL 风格中与 insert 的使用方式。话虽如此,Postgres 的问题实际上似乎是 VALUES 子句需要作为子查询包装在括号中,以便它有资格与 select 一起使用(否则它将不起作用)。因此,我们可以将以下内容视为等同于任何其他子查询:

select *
from
(
    values (1,'a'), (2, 'b')
) t;

如果VALUES 子句被替换为选择,我们将不得不为子查询设置别名,VALUES 也是如此。至于为什么 Postgres 选择这样做,您可能需要查看文档或在他们的论坛上提问。

【讨论】:

以上是关于PostgreSQL 中 VALUES 子句的行为的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 隔离级别的行为

PostgreSQL 与 array_to_json 的奇怪行为

PostgreSQL HAVING 子句

PostgreSQL HAVING 子句

PostgreSQL 中的 SQL JOIN - WHERE 子句中的执行计划与 ON 子句中的不同

在 PostgreSQL 的 WHERE 子句中使用函数结果