PERBARUI
MySQL 8.0 memperkenalkan "fungsi jendela", fungsionalitas yang setara dengan "fungsi jendela" SQL Server (dengan partisi dan pemesanan disediakan oleh Transact-SQL OVER
sintaks), dan Oracle "fungsi analitik".
Manual Referensi MySQL 12.21 Fungsi Jendela https://dev.mysql .com/doc/refman/8.0/en/window-functions.html
Jawaban yang diberikan di sini adalah pendekatan untuk versi MySQL sebelum 8.0.
JAWABAN ASLI
MySQL tidak menyediakan fungsi analitik jenis yang akan Anda gunakan untuk menjalankan "jumlah kumulatif", seperti fungsi analitik yang tersedia di DBMS lain (seperti Oracle atau SQL Server.)
Namun, dimungkinkan untuk meniru beberapa fungsi analitik, menggunakan MySQL.
Ada (setidaknya) dua pendekatan yang bisa diterapkan:
Salah satunya adalah dengan menggunakan subquery yang berkorelasi untuk mendapatkan subtotal. Pendekatan ini bisa mahal pada set besar, dan rumit jika predikat pada kueri luar rumit. Itu benar-benar tergantung pada seberapa rumit "penggabungan banyak pada beberapa tabel" itu. (Sayangnya, MySQL juga tidak mendukung CTE.)
Pendekatan lainnya adalah dengan menggunakan variabel pengguna MySQL, untuk melakukan beberapa pemrosesan istirahat kontrol. "Trik" di sini adalah untuk hasil dari kueri Anda yang diurutkan (menggunakan ORDER BY) dan kemudian membungkus kueri Anda dengan kueri lain.
Saya akan memberikan contoh pendekatan yang terakhir.
Karena urutan MySQL melakukan operasi, cumulative_total
kolom perlu dihitung sebelum nilai dari id
dan day
dari baris saat ini disimpan ke dalam variabel pengguna. Paling mudah untuk menempatkan kolom ini terlebih dahulu.
Tampilan sebaris alias i (dalam kueri di bawah) hanya ada di sana untuk menginisialisasi variabel pengguna, untuk berjaga-jaga jika ini sudah disetel dalam sesi. Jika mereka sudah memiliki nilai yang ditetapkan, kami ingin mengabaikan nilai mereka saat ini, dan cara termudah untuk melakukannya adalah dengan menginisialisasinya.
Kueri asli Anda dibungkus dalam tanda kurung, dan diberi alias, c
dalam contoh di bawah ini. Satu-satunya perubahan pada kueri asli Anda adalah penambahan klausa ORDER BY, sehingga kami dapat memastikan bahwa kami memproses baris dari kueri secara berurutan.
Pilihan luar memeriksa apakah id
dan day
nilai dari baris saat ini "cocok" dengan baris sebelumnya. Jika ya, kami menambahkan amount
dari baris saat ini ke subtotal kumulatif. Jika tidak cocok, maka kami menyetel ulang subtotal kumulatif ke nol, dan menambahkan jumlah dari baris saat ini (atau, lebih sederhana, cukup menetapkan jumlah dari baris saat ini).
Setelah kita melakukan perhitungan total kumulatif, kita simpan id
dan day
nilai dari baris saat ini ke dalam variabel pengguna, sehingga tersedia saat kami memproses baris berikutnya.
Misalnya:
SELECT IF(@prev_id = c.id AND @prev_day = c.day
,@cumtotal := @cumtotal + c.amount
,@cumtotal := c.amount) AS cumulative_total
, @prev_id := c.id AS `id`
, @prev_day := c.day AS `day`
, c.hr
, c.amount AS `amount'
FROM ( SELECT @prev_id := NULL
, @prev_day := NULL
, @subtotal := 0
) i
JOIN (
select id, day, hr, amount from
( //multiple joins on multiple tables)a
left join
(//unions on multiple tables)b
on a.id=b.id
ORDER BY 1,2,3
) c
Jika perlu untuk mengembalikan kolom dalam urutan yang berbeda, dengan total kumulatif sebagai kolom terakhir, maka satu opsi adalah untuk membungkus seluruh pernyataan itu dalam satu set parens, dan menggunakan kueri itu sebagai tampilan sebaris:
SELECT d.id
, d.day
, d.hr
, d.amount
, d.cumulative_total
FROM (
// query from above
) d