Rumah >pangkalan data >tutorial mysql >Mengapa SQL Saya COUNT(*) Mengagregatkan Semua Baris Daripada Menghimpunkan mengikut ID dan Poster?
*KIRAAN SQL() Mengagregat Baris yang Salah: Satu Perangkap Biasa**
Cabaran yang kerap dalam pertanyaan SQL melibatkan COUNT(*)
fungsi agregat secara tidak dijangka mengira semua baris dan bukannya melaksanakan kumpulan yang dimaksudkan. Ini selalunya berpunca daripada peletakan atau peninggalan klausa GROUP BY
yang salah.
Mari kita periksa pertanyaan bermasalah dan penyelesaiannya:
Pertanyaan asal bertujuan untuk mengira baris berdasarkan status "Aura", dikumpulkan mengikut "Poster" dan "ID":
<code class="language-sql">SELECT `ID`, `To`, `Poster`, `Content`, `Time`, ifnull(`Aura`,0) as `Aura` FROM ( SELECT * FROM ( SELECT DISTINCT * FROM messages m INNER JOIN ( SELECT Friend2 as Friend FROM friends WHERE Friend1 = '1' UNION ALL SELECT Friend1 as Friend FROM friends WHERE Friend2 = '1' ) friends ON m.Poster = friends.`Friend` UNION ALL SELECT DISTINCT *, '1' FROM messages where `Poster`='1' ) var LEFT JOIN ( select `ID` as `AuraID`, `Status` as `AuraStatus`, count(*) as `Aura` from messages_aura ) aura ON (var.Poster = aura.AuraID AND var.ID = aura.AuraStatus) ) final GROUP BY `ID`, `Poster` ORDER BY `Time` DESC LIMIT 10</code>
Hasil yang dijangkakan, kiraan kejadian "Aura" setiap gabungan "Poster" dan "ID" (mis., ID 1, Poster 2 yang mempunyai 2 tika Aura), tidak tercapai. Fungsi COUNT(*)
dalam subkueri salah mengagregatkan semua baris daripada messages_aura
.
Penyelesaian: Pengumpulan yang Betul dengan GROUP BY
Masalahnya terletak pada ketiadaan klausa GROUP BY
dalam subkueri yang bercantum dengan messages_aura
. Pertanyaan yang dibetulkan ialah:
<code class="language-sql">SELECT `ID`, `To`, `Poster`, `Content`, `Time`, ifnull(`Aura`,0) as `Aura` FROM ( SELECT * FROM ( SELECT DISTINCT * FROM messages m INNER JOIN ( SELECT Friend2 as Friend FROM friends WHERE Friend1 = '1' UNION ALL SELECT Friend1 as Friend FROM friends WHERE Friend2 = '1' ) friends ON m.Poster = friends.`Friend` UNION ALL SELECT DISTINCT *, '1' FROM messages where `Poster`='1' ) var LEFT JOIN ( select `ID` as `AuraID`, `Status` as `AuraStatus`, count(*) as `Aura` from messages_aura GROUP BY AuraID, AuraStatus -- The crucial addition ) aura ON (var.Poster = aura.AuraID AND var.ID = aura.AuraStatus) ) final GROUP BY `ID`, `Poster` ORDER BY `Time` DESC LIMIT 10</code>
Dengan menambahkan GROUP BY AuraID, AuraStatus
pada pernyataan SELECT
dalaman, fungsi COUNT(*)
kini mengira baris dengan betul untuk setiap gabungan unik AuraID
dan AuraStatus
, menghasilkan hasil terkumpul yang diingini. Ini memastikan bahawa Aura
dikira dengan tepat pada tahap baris. Klausa GROUP BY
luar kemudiannya mengagregatkan lagi hasil berdasarkan ID
dan Poster
.
Atas ialah kandungan terperinci Mengapa SQL Saya COUNT(*) Mengagregatkan Semua Baris Daripada Menghimpunkan mengikut ID dan Poster?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!