Buat fungsi agregat Anda sendiri , yang dapat digunakan sebagai fungsi jendela.
Fungsi agregat khusus
Ini lebih mudah dari yang diperkirakan:
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
);
Kemudian:
SELECT *, sum_cap50(val) OVER (PARTITION BY fk
ORDER BY created) > 50 AS threshold_met
FROM test
WHERE fk = 5;
Hasil persis seperti yang diminta.
db<>fiddle di sini
Lama sqlfiddle
Fungsi agregat umum
Untuk membuatnya berfungsi untuk ambang apa pun dan jenis data (numerik) apa pun , dan juga izinkan NULL
nilai :
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'
);
Kemudian, untuk memanggil dengan batas, katakanlah, 110 dengan jenis numerik apa pun:
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 di sini
Lama sqlfiddle
Penjelasan
Dalam kasus Anda, kami tidak perlu bertahan melawan NULL
nilai sejak val
didefinisikan NOT NULL
. Jika NULL
dapat terlibat, tentukan f_sum_cap()
sebagai STRICT
dan berhasil karena (per dokumentasi
):
Baik fungsi maupun agregat membutuhkan satu argumen lagi. Untuk polimorfik varian itu bisa berupa tipe data kode keras atau tipe polimorfik yang sama dengan argumen utama.
Tentang fungsi polimorfik:
Perhatikan penggunaan literal string yang tidak diketik , bukan literal numerik, yang akan menjadi default integer
!