在PostgreSQL中什么是g(i)in:FROM generate_subscripts($ 1,1)g(i)?

fve*_*vel 4 sql postgresql

这是在postgres手册中:

CREATE or replace FUNCTION mleast(a VARIADIC numeric[]) 
   RETURNS numeric 
AS $$
   SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
$$ LANGUAGE SQL;

SELECT mleast(10, -1, 5, 4.4);
Run Code Online (Sandbox Code Playgroud)

如果我写:(省略g(i))

CREATE or replace FUNCTION mleast(a VARIADIC numeric[]) 
   RETURNS numeric 
AS $$
  SELECT min($1[i]) FROM generate_subscripts($1, 1);
$$ LANGUAGE SQL;


SELECT mleast(10, -1, 5, 4.4);
Run Code Online (Sandbox Code Playgroud)

我收到:错误不存在列«i»

g(i)究竟是什么?

小智 11

generate_subscripts是一个"set-returning函数",当你调用它时会返回多行.这就是为什么它最常放在FROM子句中.

默认情况下,来自Postgres内置的generate_subscripts的结果是匿名的,并且自动具有任何名称以用作句柄,以便在查询的其余部分中引用它.这就是g(i); 它是表(g)的别名和generate_subscripts返回的列(i).所以这个表达式:

FROM generate_subscripts($1, 1) g(i)

手段:

执行函数generate_subscripts并将其结果分配给名为"g"的表,其中一列名为"i"

或者以SQL形式:

CREATE TABLE g ( i integer );

INSERT INTO g SELECT * FROM generate_subscripts(some_array, 1);

SELECT i FROM g ORDER BY i;

如果没有该别名,查询的SELECT部分​​就不知道如何引用generate_subscripts生成的结果.

使用g(i)和gs(i)是Postgres世界的惯例."g"或"gs"代表"generate_series"或"generate_subscripts"."i"是"迭代器"的传统编程变量.您实际上可以使用您想要的任何别名,我鼓励您使用实际引用您尝试执行的操作的别名,以便改进将来的代码维护.例如:

FROM generate_subscripts( $1, 1 ) as features(feature_no)

这些函数在PostgreSQL文档中有详细介绍,它也可用于引用有关如何编写集合返回函数文档(向下滚动到35.4.8.SQL函数返回集).一旦你自己编写了一个,就会更清楚为什么你需要一个别名来引用它的结果.