Opret din egen aggregerede funktion , som kan bruges som vinduesfunktion.
Specialiseret aggregeret funktion
Det er nemmere end man skulle tro:
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
);
Så:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Resultat nøjagtigt som ønsket.
db<>fiddle her
Gamle sqlfiddle
Generisk aggregatfunktion
For at få det til at fungere for enhver tærskel og enhver (numerisk) datatype , og også tillad NULL
værdier :
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'
);
For derefter at ringe med en grænse på f.eks. 110 med en hvilken som helst numerisk 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 her
Gamle sqlfiddle
Forklaring
I dit tilfælde behøver vi ikke at forsvare os mod NULL
værdier siden val
er defineret NOT NULL
. Hvis NULL
kan være involveret, skal du definere f_sum_cap()
som STRICT
og det virker, fordi (pr. dokumentation
):
Både funktion og aggregeret tager et argument mere. Til polymorfe variant det kan være en hårdkodet datatype eller den samme polymorfe type som de førende argumenter.
Om polymorfe funktioner:
Bemærk brugen af utypestrengede bogstaver , ikke numeriske bogstaver, som som standard ville være integer
!