MySQL dengan cekap memperoleh rekod terakhir setiap kumpulan
Dalam SQL, mengekstrak rekod terkini untuk setiap kumpulan boleh menjadi rumit. Senario biasa ialah: terdapat berbilang rekod dalam jadual yang berkongsi kunci utama yang sama dan entri terkini untuk setiap kunci utama perlu diekstrak. Artikel ini menyediakan penyelesaian yang cekap dan optimum.
Huraian Masalah
Pertimbangkan jadual messages
berikut:
Id | Name | Other_Columns |
---|---|---|
1 | A | A_data_1 |
2 | A | A_data_2 |
3 | A | A_data_3 |
4 | B | B_data_1 |
5 | B | B_data_2 |
6 | C | C_data_1 |
Pertanyaan kumpulan asas menggunakan SELECT * FROM messages GROUP BY Name
menghasilkan keputusan berikut:
Id | Name | Other_Columns |
---|---|---|
1 | A | A_data_1 |
4 | B | B_data_1 |
6 | C | C_data_1 |
Walau bagaimanapun, output yang diingini ialah rekod terkini untuk setiap kumpulan:
Id | Name | Other_Columns |
---|---|---|
3 | A | A_data_3 |
5 | B | B_data_2 |
6 | C | C_data_1 |
Penyelesaian
Gunakan fungsi tetingkap (MySQL 8.0 dan lebih baru)
MySQL 8.0 memperkenalkan fungsi tetingkap, yang menyediakan penyelesaian yang elegan untuk mencari rekod terakhir setiap kumpulan. Pertanyaan berikut menggunakan fungsi ROW_NUMBER()
untuk mencapai ini:
<code class="language-sql">WITH ranked_messages AS ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn FROM messages AS m ) SELECT * FROM ranked_messages WHERE rn = 1;</code>
Gunakan LEFT JOIN (versi awal MySQL)
Sebelum MySQL 8.0, penyelesaian yang paling berkesan ialah menggunakan LEFT JOIN
:
<code class="language-sql">SELECT m1.* FROM messages m1 LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id) WHERE m2.id IS NULL;</code>
Prestasi dan kebolehgunaan
Walaupun kedua-dua penyelesaian adalah cekap, prestasinya mungkin berbeza-beza bergantung pada saiz dan pengedaran data. Untuk set data yang besar dan pelbagai, pendekatan fungsi tetingkap sering disyorkan.
Jika data menunjukkan corak tertentu (cth. rekod yang agak sedikit bagi setiap kumpulan), pendekatan LEFT JOIN
mungkin lebih cekap.
Tanda Aras
Pendekatan LEFT JOIN
telah terbukti lebih baik daripada teknik pengelompokan dalam banyak kes. Contohnya, dalam pangkalan data yang besar dengan berjuta-juta baris, kaedah LEFT JOIN
mengambil masa kurang daripada satu saat untuk dilaksanakan, manakala teknik pengumpulan mengambil masa lebih daripada satu minit.
Walau bagaimanapun, anda sentiasa disyorkan untuk menguji kedua-dua penyelesaian pada set data khusus anda untuk menentukan pendekatan terbaik.
Atas ialah kandungan terperinci Bagaimana untuk mencari rekod terakhir dalam setiap kumpulan di MySQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!