Maak uw eigen verzamelfunctie , die als vensterfunctie kan worden gebruikt.
Gespecialiseerde aggregatiefunctie
Het is makkelijker dan je zou denken:
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
);
Dan:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Resultaat precies zoals gevraagd.
db<>fiddle hier
Oude sqlfiddle
Algemene aggregatiefunctie
Om het te laten werken voor alle drempels en elk (numeriek) gegevenstype , en ook sta NULL
toe waarden :
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'
);
Om vervolgens te bellen met een limiet van bijvoorbeeld 110 met een willekeurig numeriek type:
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
Oude sqlfiddle
Uitleg
In jouw geval hoeven we ons niet te verdedigen tegen NULL
waarden sinds val
is gedefinieerd NOT NULL
. Als NULL
betrokken kan zijn, definieer f_sum_cap()
als STRICT
en het werkt omdat (per documentatie
):
Zowel functie als aggregaat hebben nog een argument. Voor de polymorfe variant kan het een hard gecodeerd gegevenstype zijn of hetzelfde polymorfe type als de leidende argumenten.
Over polymorfe functies:
Let op het gebruik van niet-getypte letterlijke tekenreeksen , geen numerieke letterlijke waarden, die standaard integer
. zouden zijn !