Untuk menghindari kemungkinan hasil yang tidak terduga ketika menggunakan GROUP BY
tanpa fungsi agregat, seperti yang digunakan dalam jawaban yang diterima , karena MySQL bebas untuk mengambil nilai APAPUN dalam kumpulan data yang dikelompokkan ketika tidak menggunakan fungsi agregat [sic] dan masalah dengan ONLY_FULL_GROUP_BY
. Harap pertimbangkan untuk menggunakan gabungan pengecualian.
Pengecualian Bergabung - Entitas yang Tidak Mendua
Dengan asumsi nama depan dan nama belakang diindeks secara unik (tidak ambigu) , alternatifnya GROUP BY
adalah menyortir menggunakan LEFT JOIN
untuk menyaring set hasil, atau dikenal sebagai pengecualian. GABUNG.
Lihat Demonstrasi
Pesanan naik (AZ)
Untuk mengambil nama depan berbeda yang dipesan oleh nama belakang dari AZ
Pertanyaan
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
Hasil
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Urutan menurun (ZA)
Untuk mengambil nama depan berbeda yang dipesan oleh nama belakang dari ZA
Pertanyaan
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
Hasil
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Anda kemudian dapat memesan data yang dihasilkan sesuai keinginan.
Pengecualian Bergabung - Entitas Mendua
Jika kombinasi nama depan dan belakang tidak unik (ambigu) dan Anda memiliki beberapa baris dengan nilai yang sama, Anda dapat memfilter hasil yang ditetapkan dengan menyertakan kondisi ATAU pada kriteria GABUNG untuk juga memfilter menurut id.
Lihat Demonstrasi
data table_name
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Pertanyaan
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
Hasil
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
Subquery Dipesan
EDIT
Jawaban asli saya menggunakan subquery yang dipesan , ditulis sebelum MySQL 5.7.5 , yang tidak lagi berlaku, karena perubahan denganONLY_FULL_GROUP_BY
. Silakan gunakan pengecualian gabungan contoh di atas saja.
Penting juga untuk dicatat; ketika ONLY_FULL_GROUP_BY
dinonaktifkan (perilaku asli sebelum MySQL 5.7.5) , penggunaan GROUP BY
tanpa fungsi agregat dapat menghasilkan hasil yang tidak terduga, karena MySQL bebas untuk memilih nilai APAPUN dalam kumpulan data yang dikelompokkan [sic] .
Berarti suatu ID
atau lastname
nilai dapat diambil yang tidak terkait dengan firstname
baris yang diambil .
PERINGATAN
Dengan MySQL GROUP BY
mungkin tidak menghasilkan hasil yang diharapkan saat digunakan bersamaORDER BY
Lihat Contoh Test Case
Metode implementasi terbaik, untuk memastikan hasil yang diharapkan, adalah dengan memfilter lingkup pengaturan hasil menggunakan subquery yang dipesan.
data table_name
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Pertanyaan
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
Hasil
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Perbandingan
Untuk menunjukkan hasil yang tidak terduga saat menggunakan GROUP BY
dalam kombinasi denganORDER BY
Pertanyaan
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
Hasil
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |