PostgreSQL中VALUES子句的行为

时间:2018-12-24 14:49:43

标签: sql postgresql syntax ansi-sql

在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')

导致错误:

enter image description here

类似地,虽然这可行(假设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)

处理集( SELECT,VALUES 等)的子句的行为的逻辑扩展是否会在其他选择中使用时假定一些内部别名,例如Postgres在使用这些别名时已经做过子句独立?

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

1 个答案:

答案 0 :(得分:0)

VALUES与select配合使用的语法肯定不同于在大多数带有插入功能的SQL中使用的语法。话虽这么说,Postgres的问题实际上似乎是VALUES子句需要作为子查询用括号括起来,才能使其与select一起使用(否则它将无法工作)。因此,我们可以认为以下内容等同于任何其他子查询:

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

如果将VALUES子句替换为select,我们将不得不给子查询加上别名,而VALUES也是如此。关于为什么 Postgres选择这样做的原因,您可能必须检查文档或在其论坛上提问。