尝试创建聚合函数:
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)
答案 0 :(得分:4)
与CASE
,COALESCE
和NULLIF
类似,GREATEST
和LEAST
列在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)
LEAST
和GREATEST
不是真正的功能;在内部,它们被解析为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
函数。