create aggregate中的语法错误

时间:2016-09-07 13:47:41

标签: postgresql aggregate aggregate-functions postgresql-9.5

尝试创建聚合函数:

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

  

GREATEST和LEAST函数从任意数量的表达式列表中选择最大值或最小值。

我找不到它:

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

2 个答案:

答案 0 :(得分:4)

CASECOALESCENULLIF类似,GREATESTLEAST列在Conditional Expressions一章中。这些SQL构造在实现时并未实现为函数..例如@Laurenz provided

手册建议:

  

提示:如果您的需求超出了这些条件的功能   表达式,您可能需要考虑编写存储过程   一种更具表现力的编程语言。

这里的术语也有点偏离,因为Postgres不支持真正的"存储过程",只是函数。 (这就是open TODO item "Implement stored procedures"的原因。)

可能会对此手册页进行锐化以避免混淆......

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

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

将其设为STRICT,这是不正确的。 LEAST(1, NULL)返回1而不是NULL

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

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

答案 1 :(得分:3)

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($1, $2)';

(感谢Erwin Brandstetter提出CALLED ON NULL INPUT以及使用LEAST的想法。)

然后您可以将聚合创建为

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

这仅适用于my_type的比较函数,否则您必须提出不同的my_least函数。