Crea la tua funzione di aggregazione , che può essere utilizzata come funzione finestra.
Funzione di aggregazione specializzata
È più facile di quanto si possa pensare:
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
);
Quindi:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Risultato esattamente come richiesto.
db<>violino qui
Vecchio sqlfiddle
Funzione di aggregazione generica
Per farlo funzionare per qualsiasi soglia e qualsiasi tipo di dati (numerico) e anche consenti NULL
valori :
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'
);
Quindi, per chiamare con un limite, diciamo, di 110 con qualsiasi tipo numerico:
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<>violino qui
Vecchio sqlfiddle
Spiegazione
Nel tuo caso non dobbiamo difenderci da NULL
valori da val
è definito NOT NULL
. Se NULL
può essere coinvolto, definire f_sum_cap()
come STRICT
e funziona perché (per documentazione
):
Sia la funzione che l'aggregato accettano un altro argomento. Per il polimorfico variante può essere un tipo di dati hardcoded o lo stesso tipo polimorfico degli argomenti principali.
Informazioni sulle funzioni polimorfiche:
Nota l'uso di letterali stringa non tipizzati , non valori letterali numerici, che per impostazione predefinita sarebbero integer
!