创建聚合时出现语法错误

Syntax error in create aggregate

正在尝试创建聚合函数:

create aggregate min (my_type) (
    sfunc = least,
    stype = my_type
);
ERROR:  syntax error at or near "least"
LINE 2:     sfunc = least,
                    ^

我错过了什么?

Although the manual calls least a function:

The GREATEST and LEAST functions select the largest or smallest value from a list of any number of expressions.

我找不到它:

\dfS least
                       List of functions
 Schema | Name | Result data type | Argument data types | Type 
--------+------+------------------+---------------------+------
(0 rows)

LEASTGREATEST 不是实函数;在内部,它们被解析为 MinMaxExpr(参见 src/include/nodes/primnodes.h)。

您可以使用这样的通用函数实现您想要的:

CREATE FUNCTION my_least(anyelement, anyelement) RETURNS anyelement
   LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT
   AS 'SELECT LEAST(, )';

(感谢 Erwin Brandstetter 的 CALLED ON NULL INPUT 和使用 LEAST 的想法。)

然后您可以将聚合创建为

CREATE AGGREGATE min(my_type) (sfunc = my_least, stype = my_type);

这只有在 my_type 有比较函数时才有效,否则你必须想出一个不同的 my_least 函数。

CASECOALESCENULLIFGREATESTLEAST同时列在Conditional Expressions. These SQL constructs are not implemented as functions .. like @Laurenz provided章节中。

手册建议:

Tip: If your needs go beyond the capabilities of these conditional expressions, you might want to consider writing a stored procedure in a more expressive programming language.

这里的术语也有点偏离,因为 Postgres 不支持真正的 "stored procedures",只支持函数。 (这就是为什么有一个 open TODO item "Implement stored procedures"。)

本手册页可能会更清晰以避免混淆...

@Laurenz 也提供了一个例子。我只想在函数中使用 LEAST 来获得相同的功能:

CREATE FUNCTION f_least(anyelement, anyelement)
  RETURNS anyelement LANGUAGE sql IMMUTABLE AS
'SELECT LEAST(, )';

STRICT,那是不正确的。 LEAST(1, NULL) returns 1 而不是 NULL.

即使STRICT是正确的,我也不会使用它,因为它会阻止函数内联。

请注意,此函数仅限于两个参数,而 LEAST 接受 任意 个参数。您可能会重载函数以覆盖 3、4 等输入参数。或者您可以为最多 100 个参数编写 VARIADIC 函数。