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 与 array_to_json 的奇怪行为