Isu biasa apabila menggunakan LEFT JOIN ialah kegagalan mengembalikan kiraan sifar untuk kumpulan tertentu. Ini sering berlaku apabila syarat penapisan diletakkan dalam klausa WHERE dan bukannya klausa JOIN. Contoh ini menunjukkan cara menyusun LEFT JOIN dengan betul untuk memastikan semua organisasi disertakan, walaupun organisasi yang mempunyai kiraan sifar.
Masalah timbul kerana salah meletakkan klausa WHERE. Pertimbangkan pertanyaan diperbetulkan ini:
<code class="language-sql">LEFT JOIN exam_items e ON e.organisation_id = o.id AND e.item_template_id = #{sanitize(item_template_id)} AND e.used</code>
Meletakkan syarat penapisan (e.item_template_id
, e.used
) dalam klausa JOIN memastikan bahawa hanya baris yang sepadan digabungkan. Sebelum ini, meletakkan syarat ini dalam klausa WHERE secara tidak sengaja mengubah LEFT JOIN menjadi INNER JOIN, tidak termasuk organisasi tanpa entri yang sepadan.
Adalah penting untuk memahami bahawa COUNT(*)
dan COUNT(e.id)
sentiasa mengembalikan nilai berangka (0 atau lebih besar), tidak seperti fungsi agregat lain yang mungkin mengembalikan NULL. Oleh itu, menggunakan COALESCE
untuk mengendalikan nilai NULL adalah tidak diperlukan dalam kes ini.
Untuk senario di mana majoriti exam_items
baris dikira, peningkatan prestasi dicapai dengan pra-mengagregatkan kiraan:
<code class="language-sql">LEFT JOIN ( SELECT organisation_id AS id -- aliased for simpler join , COUNT(*) AS total_used -- COUNT(*) is generally faster FROM exam_items WHERE item_template_id = #{sanitize(item_template_id)} AND used GROUP BY 1 ) e USING (id)</code>
Pendekatan yang dioptimumkan ini mula-mula mengagregatkan kiraan daripada exam_items
, kemudian melakukan gabungan yang lebih mudah dengan jadual organisasi. Ini boleh meningkatkan kelajuan pertanyaan dengan ketara, terutamanya dengan set data yang besar.
Atas ialah kandungan terperinci Mengapa SERTAI KIRI Saya Tidak Mengembalikan Sifar Dikira untuk Organisasi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!