PostgreSQL:为什么子查询作为表达式不能返回多行,但函数可以?

6

如果我尝试创建一个列,其值是返回多行的 select 语句,那么就会出现错误。

=> select (select 1 union select 2);
ERROR:  more than one row returned by a subquery used as an expression

但如果我创建一个做同样事情的函数,我就能得到我想要的行为。

=> create or replace function onetwo() returns setof integer as $$
$> select 1 union select 2 
$> $$ language 'sql' strict immutable;
CREATE FUNCTION
=> select onetwo();
 onetwo 
--------
      1
      2

为什么会有差异?
2个回答

5

这不是苹果和苹果的比较。

select * 
  FROM (select 1 
        union ALL 
        select 2)

...相当于您的函数。

在SELECT子句中的列每条记录只能返回单个值。这在您的UNION示例中是不可能的。因此,我将其转换为一个派生表/内联视图,这就是函数示例中正在发生的事情。


4
虽然OMG Ponies的答案完全正确,但我更愿意这样说:您将SELECT f()SELECT literal混淆了。 SELECT f() 执行一个函数并返回其结果。而且,一个返回表格的函数也可以写成SELECT * FROM f()——这甚至更加优雅。因为Pg还没有存储过程——少调度可以通过函数完成——我们使用SELECT就像Microsoft SQL使用EXECUTE SELECT LITERAL是一种返回字面值(可以适合在行/列中)的方法。

1
+1,我认为我已经看到过将SELECT f()(用于返回集合的函数f)形式描述为SELECT * FROM f()的语法糖。它只是被实现是因为它是明确的和方便的简写。 - Edmund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接