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
の行は無視されます 入力。また、3番目の配列要素を設定して、1つ以上の入力行を持つセットを識別します。それ以外の場合は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
を返します どちらの場合も。