PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Penambahan kumulatif dengan basis dinamis di Postgres

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 !




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara memperbarui banyak catatan menggunakan peewee

  2. Bagaimana cara mengubah kosong menjadi nol di PostgreSQL?

  3. Bagaimana cara menyalin struktur satu tabel ke tabel lain dengan batasan kunci asing di psql?

  4. TIDAK DI di postgresql tidak berfungsi

  5. Dalam fungsi pemicu, cara mendapatkan bidang mana yang diperbarui