Crie sua própria função agregada , que pode ser usado como função de janela.
Função de agregação especializada
É mais fácil do que se imagina:
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
);
Então:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Resultado exatamente como solicitado.
db<>fiddle aqui
Antigo sqlfiddle
Função de agregação genérica
Para que funcione para qualquer limite e qualquer tipo de dado (numérico) , e também permitir
NULL
valores :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'
);
Então, para chamar com um limite de, digamos, 110 com qualquer tipo numérico:
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 aqui
Antigo sqlfiddle
Explicação
No seu caso, não precisamos nos defender contra
NULL
valores desde val
está definido NOT NULL
. Se NULL
pode estar envolvido, defina f_sum_cap()
como STRICT
e funciona porque (por documentação
):Tanto a função quanto a agregação recebem mais um argumento. Para o polimórfico variante pode ser um tipo de dados codificado ou o mesmo tipo polimórfico dos argumentos principais.
Sobre funções polimórficas:
Observe o uso de literais de string não tipados , não literais numéricos, cujo padrão seria
integer
!