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

Menghitung Jumlah Kumulatif di PostgreSQL

Pada dasarnya, Anda memerlukan fungsi jendela. Itu fitur standar saat ini. Selain fungsi jendela asli, Anda dapat menggunakan apa saja fungsi agregat sebagai fungsi jendela di Postgres dengan menambahkan OVER klausa.

Kesulitan khusus di sini adalah untuk mendapatkan partisi dan mengurutkan urutan yang benar:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id
                         ORDER BY ea_year, ea_month) AS cum_amt
FROM   tbl
ORDER  BY circle_id, month;

Dan tidak GROUP BY .

Jumlah untuk setiap baris dihitung dari baris pertama di partisi ke baris saat ini - atau lebih tepatnya mengutip manual:

Opsi pembingkaian default adalah RANGE UNBOUNDED PRECEDING , yang sama dengan RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW . DenganORDER BY , ini menetapkan bingkai menjadi semua baris dari partisimulai hingga ORDER BY terakhir baris saat ini rekan .

... yang merupakan jumlah kumulatif atau berjalan yang Anda cari. Penekanan saya yang berani.

Baris dengan (circle_id, ea_year, ea_month) yang sama adalah "rekan" dalam kueri ini. Semua itu menunjukkan jumlah berjalan yang sama dengan semua rekan ditambahkan ke jumlah tersebut. Tapi saya menganggap tabel Anda UNIQUE pada (circle_id, ea_year, ea_month) , maka urutan pengurutannya adalah deterministik dan tidak ada baris yang memiliki rekan.

Postgres 11 menambahkan alat untuk menyertakan / mengecualikan rekan dengan frame_exclusion baru pilihan. Lihat:

  • Menggabungkan semua nilai yang tidak berada dalam grup yang sama

Sekarang, ORDER BY ... ea_month tidak akan berfungsi dengan string untuk nama bulan . Postgres akan mengurutkan berdasarkan abjad sesuai dengan pengaturan lokal.

Jika Anda memiliki date yang sebenarnya nilai yang disimpan di tabel Anda, Anda dapat mengurutkan dengan benar. Jika tidak, saya sarankan untuk mengganti ea_year dan ea_month dengan satu kolom mon jenis date di meja Anda.

  • Ubah apa yang Anda miliki dengan to_date() :

      to_date(ea_year || ea_month , 'YYYYMonth') AS mon
    
  • Untuk tampilan, Anda bisa mendapatkan string asli dengan to_char() :

      to_char(mon, 'Month') AS ea_month
      to_char(mon, 'YYYY') AS ea_year
    

Saat terjebak dengan desain yang tidak menguntungkan, ini akan berhasil:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
FROM   (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
ORDER  BY circle_id, mon;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa mengubah kolom yang ada sebagai Identitas di PostgreSQL 11.1

  2. Opsi Failover Cluster Basis Data Lengkap Multi-Cloud untuk PostgreSQL

  3. Ketik string ke integer

  4. Mengapa Postgres tidak menggunakan indeks?

  5. Cara Membuat Array di PostgreSQL