Petua untuk mengelakkan pendaraban nilai SUM apabila menggunakan fungsi agregat untuk menyertai jadual dalam MySQL
Apabila menggabungkan berbilang operasi gabungan dalam pertanyaan MySQL, menggunakan fungsi agregat seperti SUM boleh membawa kepada hasil yang tidak dijangka. Ini kerana hasil darab Cartesian baris bagi jadual cantuman mendarabkan hasil penjumlahan, menghasilkan keputusan yang tidak tepat.
Andaikan terdapat contoh di mana dua pertanyaan pada mulanya digunakan untuk mendapatkan nilai SUM daripada jadual yang berbeza. Pertanyaan 1 mengira jumlah masa memandu untuk pekerja tertentu dalam julat tarikh tertentu, manakala Pertanyaan 2 mengira jumlah masa bekerja untuk pekerja yang sama dalam tempoh yang sama.
Cuba untuk menggabungkan pertanyaan ini menjadi satu pertanyaan penyertaan akan menghasilkan jumlah yang salah. Ini kerana operasi JOIN mencipta produk Cartesian bagi baris jadual bhds_timecard
dan bhds_mileage
. Akibatnya, nilai SUM untuk masa memandu dan masa kerja didarab dengan bilangan baris yang sepadan dalam setiap jadual.
Untuk menyelesaikan masalah ini, anda boleh menggunakan subquery untuk mengira nilai SUM sebelum menyertai jadual. Dengan mengalihkan operasi SUM ke subkueri berasingan, anda boleh menghalang produk Cartesian dan mendapatkan hasil yang tepat.
Berikut ialah pertanyaan yang ditambah baik menggunakan subkueri:
<code class="language-sql">SELECT last_name, first_name, DATE_FORMAT(LEAST(mil_date, tm_date), '%m/%d/%y') AS dates, total, minutes FROM bhds_teachers AS i LEFT JOIN ( SELECT ds_id, YEARWEEK(mil_date) AS week, MIN(mil_date) AS mil_date, SUM(drive_time) AS minutes FROM bhds_mileage WHERE mil_date BETWEEN '2016-04-11' AND '2016-04-30' AND bhds_mileage.ds_id = 5 GROUP BY ds_id, week ) AS m ON m.ds_id = i.ds_id LEFT JOIN ( SELECT ds_id, YEARWEEK(tm_date) AS week, MIN(tm_date) AS tm_date, SUM(tm_hours) AS total FROM bhds_timecard WHERE tm_date BETWEEN '2016-04-11' AND '2016-04-30' AND bhds_timecard.ds_id = 5 GROUP BY ds_id, week ) AS t ON t.ds_id = i.ds_id AND t.week = m.week;</code>
Dalam pertanyaan ini:
m
Mengira jumlah masa memandu yang dikumpulkan mengikut ID pekerja dan minggu. t
Mengira jumlah jam bekerja dikumpulkan mengikut ID pekerja dan minggu. bhds_teachers
dengan subkueri m
dan t
. Akibatnya, pertanyaan mendapatkan semula nama akhir, nama pertama, tarikh, jumlah masa kerja dan jumlah masa memandu untuk pekerja dan tempoh yang ditentukan tanpa masalah mendarab nilai SUM.
Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Nilai SUM Berganda Apabila Menyertai Jadual dengan Fungsi Agregat dalam MySQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!