Rumah >pangkalan data >tutorial mysql >Mengapa Pertanyaan LEFT JOIN Saya Tidak Mengembalikan Organisasi dengan Kiraan Sifar?

Mengapa Pertanyaan LEFT JOIN Saya Tidak Mengembalikan Organisasi dengan Kiraan Sifar?

Patricia Arquette
Patricia Arquetteasal
2025-01-14 11:57:46269semak imbas

Why Doesn't My LEFT JOIN Query Return Organizations with a Count of Zero?

PostgreSQL LEFT JOIN: Menangani Isu Organisasi Kiraan Sifar

Cabaran biasa apabila menggunakan LEFT JOIN dalam PostgreSQL melibatkan mendapatkan semula kiraan rekod yang berkaitan. Jika kiraan adalah sifar untuk organisasi tertentu, organisasi itu mungkin diabaikan daripada keputusan. Artikel ini menangani masalah ini.

Pertanyaan berikut cuba mengira item terpakai bagi setiap organisasi:

<code class="language-sql">SELECT o.name as organisation_name,
         coalesce(COUNT(exam_items.id)) as total_used
  FROM organisations o
  LEFT JOIN exam_items e on o.id = e.organisation_id
  WHERE e.item_template_id = #{sanitize(item_template_id)}
  and e.used = true
  GROUP BY o.name
  ORDER BY o.name</code>

Kesilapan pertanyaan ini terletak pada klausa WHERE. Syarat yang diletakkan dalam WHERE penapis klausa selepas gabungan, menjadikan LEFT JOIN menjadi INNER JOIN dengan berkesan apabila rekod yang sepadan tidak ditemui dalam exam_items.

Berikut ialah versi yang dipertingkatkan:

Penyelesaian 1: Membetulkan Syarat JOIN

Fasal WHERE menapis organisasi dengan kiraan sifar. Memindahkan syarat item_template_id dan used ke dalam klausa ON LEFT JOIN menyelesaikan perkara ini:

<code class="language-sql">SELECT o.name AS organisation_name, COUNT(e.id) AS total_used
FROM organisations o
LEFT JOIN exam_items e ON e.organisation_id = o.id AND e.item_template_id = #{sanitize(item_template_id)} AND e.used
GROUP BY o.name
ORDER BY o.name;</code>

Pertanyaan yang disemak ini memastikan semua organisasi disertakan, walaupun yang tiada entri yang sepadan dalam exam_items.

Penyelesaian 2: Pra-Penggabungan untuk Kecekapan

Untuk set data yang lebih besar, pra-pengagregatan exam_items boleh meningkatkan prestasi dengan ketara:

<code class="language-sql">SELECT o.id, o.name AS organisation_name, COALESCE(e.total_used, 0) AS total_used
FROM organisations o
LEFT JOIN (
   SELECT organisation_id AS id, COUNT(*) AS total_used
   FROM exam_items
   WHERE item_template_id = #{sanitize(item_template_id)} AND used = TRUE
   GROUP BY 1
) e ON o.id = e.id
ORDER BY o.name, o.id;</code>

Pendekatan ini mula-mula mengagregatkan kiraan untuk setiap organisasi dan kemudian melaksanakan LEFT JOIN, menghasilkan pertanyaan yang lebih cekap. Perhatikan penggunaan COALESCE untuk mengendalikan kes di mana total_used adalah NULL.

Dengan melaksanakan salah satu daripada penyelesaian ini, anda akan mendapatkan semula kiraan item terpakai dengan tepat untuk semua organisasi, termasuk yang mempunyai kiraan sifar. Pilih penyelesaian yang paling sesuai dengan saiz data dan keperluan prestasi anda.

Atas ialah kandungan terperinci Mengapa Pertanyaan LEFT JOIN Saya Tidak Mengembalikan Organisasi dengan Kiraan Sifar?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn