Sie können ein ARRAY verwenden intern eingeben. Der Argumenttyp kann weiterhin ein beliebiger numerischer Typ sein. Demonstration mit 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}'
);
Die Übergangsfunktion f_circavg()
ist STRICT
definiert , also ignoriert es Zeilen mit NULL
Eingang. Es setzt auch ein drittes Array-Element, um Sets mit einer oder mehreren Eingabezeilen zu identifizieren - ansonsten den CASE
die letzte Funktion gibt NULL
zurück .
Temporäre Tabelle zum Testen:
CREATE TEMP TABLE t (x float);
INSERT INTO t VALUES (2), (NULL), (3), (4), (5);
Ich habe einen NULL
eingefügt -Wert, um auch STRICT
zu testen Magie. Aufruf:
SELECT circavg(x) FROM t;
circavg
-------------------
-2.78318530717959
Gegenprobe:
SELECT atan2(sum(sin(x)), sum(cos(x))) FROM t;
atan2
-------------------
-2.78318530717959
Gibt das gleiche zurück. Scheint zu funktionieren. Im Test mit einer größeren Tabelle war der letzte Ausdruck mit regulären Aggregatfunktionen 4x schneller als das benutzerdefinierte Aggregat.
Test auf null Eingabezeilen / nur NULL-Eingabe:
SELECT circavg(x) FROM t WHERE false; -- no input rows
SELECT circavg(x) FROM t WHERE x IS NULL; -- only NULL input
Gibt NULL
zurück in beiden Fällen.