Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Mengelakkan Pendua dalam `GROUP_CONCAT` Apabila Menyertai Berbilang `GROUP_BY`?
Mengatasi Keputusan Pendua dalam GROUP_CONCAT
dengan Berbilang GROUP BY
Gabungan
Menggabungkan berbilang GROUP BY
klausa melalui LEFT JOIN
s dan menggunakan GROUP_CONCAT
boleh membawa kepada pendua entri. Ini timbul daripada penggabungan kunci unik daripada setiap GROUP BY
, mengakibatkan perwakilan data yang tidak tepat.
Senario Masalah
Pertimbangkan struktur pertanyaan ini:
<code class="language-sql">SELECT q1.user_id, q1.user_name, q1.score, q1.reputation, SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags, SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category FROM (...) AS q1 LEFT JOIN (...) AS q2 ON q2.user_id = q1.user_id LEFT JOIN (...) AS q3 ON q3.user_id = q1.user_id GROUP BY q1.user_id, q1.user_name, q1.score, q1.reputation</code>
Pertanyaan ini bertujuan untuk mendapatkan semula dua teg dan kategori teratas untuk setiap pengguna, dengan mengandaikan jadual untuk pengguna, teg, reputasi, post_tag
, kategori dan post_category
. Masalahnya ialah potensi pendua seperti "css,css" atau "technology,technology" disebabkan oleh GROUP BY
s yang digabungkan.
Penyelesaian Berkesan
Beberapa kaedah boleh menghalang pendua ini:
1. Asingkan GROUP BY
dan SERTAI DALAM:
<code class="language-sql">-- Separate grouping and joining approach SELECT q1.user_id, q1.user_name, q1.score, q1.reputation, q1.top_two_tags, q2.category FROM (SELECT q1.user_id, q1.user_name, q1.score, q1.reputation, SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags FROM (...) AS q1 LEFT JOIN (...) AS q2 ON q2.user_id = q1.user_id GROUP BY q1.user_id, q1.user_name, q1.score, q1.reputation ) AS q1 INNER JOIN (SELECT q1.user_id, SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category FROM (...) AS q1 LEFT JOIN (...) AS q3 ON q3.user_id = q1.user_id GROUP BY q1.user_id ) AS q2 ON q1.user_id = q2.user_id;</code>
Kaedah ini mula-mula mengumpulkan dan menggabungkan teg dan kategori secara berasingan, kemudian menggabungkan hasil menggunakan INNER JOIN
pada user_id
. Ini memastikan hanya satu baris bagi setiap pengguna dihasilkan.
2. Subqueries Skalar:
<code class="language-sql">-- Scalar subquery approach SELECT q1.user_id, q1.user_name, q1.score, q1.reputation, (SELECT SUBSTRING_INDEX(GROUP_CONCAT(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) FROM (...) AS q2 WHERE q2.user_id = q1.user_id ), (SELECT SUBSTRING_INDEX(GROUP_CONCAT(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) FROM (...) AS q3 WHERE q3.user_id = q1.user_id ) FROM (...) AS q1;</code>
Ini menggunakan subkueri dalam senarai SELECT
untuk mengambil teg dan kategori teratas bagi setiap pengguna secara individu, mengelakkan kekaburan GROUP BY
.
Kuncinya adalah untuk mengelak daripada menggabungkan data secara langsung daripada berbilang jadual yang digabungkan dalam satu panggilan GROUP_CONCAT
apabila menggunakan GROUP BY
pada berbilang jadual. Penyelesaian yang dipilih bergantung pada struktur pangkalan data khusus dan pertimbangan prestasi. Matlamatnya adalah untuk menghasilkan keputusan yang tepat dan bebas pendua.
Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Pendua dalam `GROUP_CONCAT` Apabila Menyertai Berbilang `GROUP_BY`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!