Erstellen Sie Ihre eigene Aggregatfunktion , die als Fensterfunktion verwendet werden kann.
Spezialisierte Aggregatfunktion
Es ist einfacher als man denkt:
CREATE OR REPLACE FUNCTION f_sum_cap50 (numeric, numeric)
RETURNS numeric LANGUAGE sql AS
'SELECT CASE WHEN $1 > 50 THEN 0 ELSE $1 END + $2';
CREATE AGGREGATE sum_cap50 (numeric) (
sfunc = f_sum_cap50
, stype = numeric
, initcond = 0
);
Dann:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Ergebnis genau wie gewünscht.
db<>fiddle hier
Altes sqlfiddle
Generische Aggregatfunktion
Damit es für alle Schwellenwerte funktioniert und beliebiger (numerischer) Datentyp , und auch NULL
zulassen Werte :
CREATE OR REPLACE FUNCTION f_sum_cap (anyelement, anyelement, anyelement)
RETURNS anyelement
LANGUAGE sql STRICT AS
$$SELECT CASE WHEN $1 > $3 THEN '0' ELSE $1 END + $2;$$;
CREATE AGGREGATE sum_cap (anyelement, anyelement) (
sfunc = f_sum_cap
, stype = anyelement
, initcond = '0'
);
Um dann mit einem Limit von, sagen wir, 110 mit einem beliebigen numerischen Typ anzurufen:
SELECT *
, sum_cap(val, '110') OVER (PARTITION BY fk
ORDER BY created) AS capped_at_110
, sum_cap(val, '110') OVER (PARTITION BY fk
ORDER BY created) > 110 AS threshold_met
FROM test
WHERE fk = 5;
db<>fiddle hier
Altes sqlfiddle
Erklärung
In Ihrem Fall müssen wir uns nicht gegen NULL
wehren Werte seit val
ist NOT NULL
definiert . Wenn NULL
beteiligt sein können, definieren Sie f_sum_cap()
als STRICT
und es funktioniert, weil (pro Dokumentation
):
Sowohl die Funktion als auch das Aggregat benötigen ein weiteres Argument. Für das polymorphe Variante kann es sich um einen hartcodierten Datentyp oder denselben polymorphen Typ wie die führenden Argumente handeln.
Über polymorphe Funktionen:
Beachten Sie die Verwendung von nicht typisierten Zeichenfolgenliteralen , keine numerischen Literale, die standardmäßig integer
wären !