您可以在内部使用ARRAY类型。参数类型仍然可以是任何数字类型。float
用(= )演示double precision
:
CREATE OR REPLACE FUNCTION f_circavg (float[], float)
RETURNS float[] LANGUAGE sql STRICT AS
'SELECT ARRAY[$1[1] + sin($2), $1[2] + cos($2), 1]';
CREATE OR REPLACE FUNCTION f_circavg_final (float[])
RETURNS float LANGUAGE sql AS
'SELECT CASE WHEN $1[3] > 0 THEN atan2($1[1], $1[2]) END';
CREATE AGGREGATE circavg (float) (
sfunc = f_circavg
, stype = float[]
, finalfunc = f_circavg_final
, initcond = '{0,0,0}'
);
转换函数f_circavg()
已定义STRICT
,因此它会忽略NULL
输入行。它还设置第三个数组元素以标识具有一个或多个输入行的集合 - 否则CASE
最终函数返回NULL
。
测试临时表:
CREATE TEMP TABLE t (x float);
INSERT INTO t VALUES (2), (NULL), (3), (4), (5);
我输入了一个NULL
值来测试STRICT
魔法。称呼:
SELECT circavg(x) FROM t;
circavg
-------------------
-2.78318530717959
交叉检查:
SELECT atan2(sum(sin(x)), sum(cos(x))) FROM t;
atan2
-------------------
-2.78318530717959
返回相同。似乎工作。在使用更大表的测试中,使用常规聚合函数的最后一个表达式比自定义聚合快 4 倍。
测试零输入行/仅 NULL 输入:
SELECT circavg(x) FROM t WHERE false; -- no input rows
SELECT circavg(x) FROM t WHERE x IS NULL; -- only NULL input
NULL
在两种情况下都返回。