MySQL Klausa GROUP BY dan HAVING dengan Contoh
โก Ringkasan Cerdas
Klausul SQL GROUP BY dan HAVING mengubah baris detail menjadi laporan ringkasan. GROUP BY menggabungkan baris yang memiliki nilai yang sama menjadi satu baris per grup, sedangkan HAVING memfilter grup tersebut setelah fungsi agregasi seperti COUNT diterapkan.

Apa itu klausa GROUP BY dalam SQL?
Klausa GROUP BY adalah perintah SQL yang digunakan untuk mengelompokkan baris-baris yang mempunyai nilai yang sama. Ini ditulis di dalam pernyataan SELECT, dan biasanya digunakan bersama dengan fungsi agregasi untuk menghasilkan laporan ringkasan dari basis data.
Itulah fungsinya: merangkum data Disimpan dalam basis data. Kueri yang berisi klausa GROUP BY disebut kueri grup, dan kueri ini mengembalikan satu baris untuk setiap item yang dikelompokkan.
SQL GROUP OLEH Sintaks
Setelah tujuan klausa tersebut jelas, mari kita lihat sintaks dari kueri grup dasar.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
SINI
- "Pernyataan SELECTโฆโ adalah standarnya SQL PILIH perintah kueri.
- "KELOMPOK OLEH kolom_nama1โ adalah klausa yang menjalankan grup tersebutping berdasarkan column_name1.
- "[, nama_kolom2, โฆ]โ bersifat opsional dan mewakili nama kolom lain ketika grup tersebutping dilakukan pada lebih dari satu kolom.
- "[MEMILIKI kondisi]โ bersifat opsional dan digunakan untuk membatasi baris yang terpengaruh oleh klausa GROUP BY. Ini mirip dengan klausa WHEREkecuali jika diterapkan setelah kelompok tersebutping.
Grouping Menggunakan Kolom Tunggal
Cara tercepat untuk melihat efek klausa SQL GROUP BY adalah dengan membandingkan kueri yang tidak dikelompokkan dengan kueri yang dikelompokkan. Mulailah dengan kueri sederhana yang mengembalikan setiap entri jenis kelamin dalam tabel anggota.
SELECT `gender` FROM `members`;
| jenis kelamin |
|---|
| Perempuan |
| Perempuan |
| Pria |
| Perempuan |
| Pria |
| Pria |
| Pria |
| Pria |
| Pria |
Sembilan baris dikembalikan, dan setiap nilai diulang. Misalkan kita menginginkan nilai unik untuk jenis kelamin. Kueri di bawah ini menambahkan klausa GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Menjalankan skrip di atas dalam MySQL Workbench terhadap myflixdb memberi kita hasil berikut.
| jenis kelamin |
|---|
| Perempuan |
| Pria |
Perhatikan bahwa hanya dua baris yang dikembalikan, karena tabel hanya memuat dua tipe gender. Klausa GROUP BY mengelompokkan semua anggota "Laki-laki" bersama-sama dan mengembalikan satu baris untuk mereka, dan hal yang sama dilakukan dengan anggota "Perempuan".
Grouping Menggunakan Beberapa Kolom
Grouping Penggunaan satu kolom saja seringkali terlalu kasar untuk laporan yang sebenarnya. GROUP BY menerima daftar kolom yang dipisahkan koma, dan kombinasi nilai-nilai kolom tersebut mendefinisikan setiap grup.
Misalkan kita menginginkan daftar nilai category_id film dan tahun rilis film tersebut. Perhatikan terlebih dahulu hasil dari kueri sederhana ini.
SELECT `category_id`, `year_released` FROM `movies`;
| kategori_id | tahun_dirilis |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Baris yang disorot menunjukkan bahwa hasilnya berisi data duplikat. Menjalankan kueri yang sama dengan GROUP BY akan menghapus data duplikat tersebut.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Menjalankan skrip di atas dalam MySQL Pengujian Workbench terhadap myflixdb memberikan hasil sebagai berikut, seperti yang ditunjukkan di bawah ini.
| kategori_id | tahun_dirilis |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Klausul GROUP BY beroperasi pada category_id dan year_released untuk mengidentifikasi unik baris. Dua baris duplikat untuk kategori 6 pada tahun 2007 digabungkan menjadi satu.
Aturan praktis: Jika ID kategori sama tetapi tahun rilis berbeda, baris tersebut dianggap unik. Jika ID kategori dan tahun rilis sama untuk lebih dari satu baris, baris tersebut dianggap duplikat dan hanya satu yang ditampilkan.
Grouping dan Fungsi Agregat
Menghapus duplikat memang berguna, tetapi kekuatan sebenarnya dari grup adalah...ping muncul ketika dipasangkan dengan fungsi agregatFungsi agregat menghitung satu nilai untuk setiap grup: COUNT menghitung baris, SUM menjumlahkan nilai, dan AVG, MIN, dan MAX menggambarkan sebaran.
Misalkan kita ingin mengetahui jumlah total anggota pria dan wanita dalam basis data. Skrip di bawah ini melakukan hal tersebut.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Menjalankan skrip di atas dalam MySQL Pengujian Workbench terhadap myflixdb memberikan hasil sebagai berikut.
| jenis kelamin | HITUNG(`nomor_keanggotaan`) |
|---|---|
| Perempuan | 3 |
| Pria | 6 |
Baris-baris tersebut dikelompokkan berdasarkan setiap nilai jenis kelamin yang unik, dan jumlah baris di dalam setiap kelompok dihitung oleh fungsi agregasi COUNT. Sembilan catatan anggota tersebut kemudian digabungkan menjadi dua baris ringkasan.
Membatasi Hasil Kueri Menggunakan Klausa HAVING
GroupingTidak selalu diperlukan data untuk setiap baris dalam tabel. Terkadang laporan harus dibatasi pada kriteria tertentu, dan itulah tugas dari klausa HAVING.
Misalkan kita ingin mengetahui semua tahun rilis untuk kategori film dengan ID 8. Skrip di bawah ini akan mencapai hasil tersebut.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Menjalankan skrip di atas dalam MySQL Pengujian Workbench terhadap myflixdb memberikan hasil sebagai berikut, seperti yang ditunjukkan di bawah ini.
| film_id | judul | direktur | tahun_dirilis | kategori_id |
|---|---|---|---|---|
| 9 | Honey mooners | John Schultz | 2005 | 8 |
| 5 | Gadis Kecil Ayah | NULL | 2007 | 8 |
Hanya film dengan ID kategori 8 yang dipertahankan oleh kondisi HAVING.
Peringatan: MySQL Versi 5.7 dan yang lebih baru mengaktifkan mode ONLY_FULL_GROUP_BY secara default, dan dalam mode tersebut SELECT * dengan klausa GROUP BY ditolak, karena movie_id, title, dan director tidak dikelompokkan atau diagregasi. Dalam produksi, sebutkan kolom yang dikelompokkan secara eksplisit, misalnya SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;
WHERE vs HAVING vs GROUP BY vs ORDER BY
Para pemula seringkali mencampuradukkan keempat klausa ini, karena semuanya membentuk himpunan hasil. Perbedaannya terletak pada ketika MySQL Menerapkan aturan berikut: WHERE dijalankan sebelum baris dikelompokkan, HAVING dijalankan setelahnya, dan ORDER BY dijalankan paling akhir.
| Ayat | Apa yang dilakukannya | Saat berjalan | Menerima fungsi agregat |
|---|---|---|---|
| MANA | Memfilter setiap baris satu per satu sebelum grup apa punping. | Sebelum MENGELOLA BERDASARKAN | Tidak |
| KELOMPOK OLEH | Menggabungkan baris yang memiliki nilai yang sama menjadi satu baris per grup. | Setelah DI MANA | Tidak berlaku |
| MEMILIKI | Memfilter grup yang dihasilkan oleh GROUP BY. | Setelah GRUP BY | Ya, misalnya HAVING COUNT(*) > 2 |
| DIPESAN OLEH | Mengurutkan baris yang tersisa setelah klausa sebelumnya. | Terakhir | Ya, alias agregat dapat diurutkan. |
Konsekuensi praktisnya adalah pada performa. Pemfilteran dengan klausa WHERE menghapus baris sebelum grup.ping Pekerjaan dimulai, jadi kondisi yang tidak bergantung pada hasil agregat termasuk dalam klausa WHERE dan bukan HAVING.
