Pengelompokan Data — SQL

GROUP BY mengelompokkan baris berdasarkan nilai kolom tertentu, biasanya dikombinasikan dengan fungsi agregat. SELECT departemen, COUNT(*) as jumlah…

GROUP BY mengumpulkan baris yang nilainya sama di satu kolom jadi satu kelompok, lalu fungsi agregat (COUNT, AVG, SUM, ...) menghitung per kelompok, bukan untuk seluruh tabel. Bayangin tumpukan slip gaji di meja HRD. Slipnya dipilah per departemen jadi tiga tumpukan, lalu tiap tumpukan dihitung: berapa lembar, berapa rata-rata gajinya. HAVING itu langkah sesudahnya: singkirkan tumpukan yang isinya kurang dari tiga.

🧪 Tebakan cepat: query SELECT departemen, COUNT(*) FROM karyawan WHERE COUNT(*) > 2 GROUP BY departemen; jalan gak? Tebak dulu, jawabannya ada di bagian "WHERE atau HAVING".

Tanpa GROUP BY: satu kelompok besar

Tabel karyawan di Lab dan latihan berisi 8 orang:

id nama departemen gaji
1 Budi IT 8000000
2 Siti IT 9000000
3 Andi IT 8500000
4 Dewi HR 6000000
5 Rizky HR 6500000
6 Maya HR 6200000
7 Dimas Marketing 7000000
8 Citra Marketing 7200000
SELECT departemen, COUNT(*) AS jumlah, AVG(gaji) AS rata_gaji
FROM karyawan;
departemen jumlah rata_gaji
IT 8 7300000

Seperti di pelajaran Fungsi Agregat, semua 8 baris jadi satu kelompok, jadi hasilnya 1 baris. IT di kolom departemen cuma nilai yang diambil SQLite dari salah satu baris, bukan ringkasan. MySQL dan PostgreSQL bahkan menolak query ini.

GROUP BY: satu baris per kelompok

SELECT departemen, COUNT(*) AS jumlah, AVG(gaji) AS rata_gaji
FROM karyawan
GROUP BY departemen;
departemen jumlah rata_gaji
HR 3 6233333.333333333
IT 3 8500000
Marketing 2 7100000

HAVING: saring kelompok

SELECT departemen, COUNT(*) AS jumlah, AVG(gaji) AS rata_gaji
FROM karyawan
GROUP BY departemen
HAVING COUNT(*) > 2;
departemen jumlah rata_gaji
HR 3 6233333.333333333
IT 3 8500000

HAVING memeriksa tiap kelompok setelah dihitung. Marketing cuma punya 2 orang, jadi dibuang. Tinggal IT dan HR.

WHERE atau HAVING

SQLite mengerjakan query dengan urutan ini: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. Saat WHERE jalan, kelompoknya belum ada, jadi COUNT(*) belum bisa dihitung. Itu jawaban tebakannya: SQLite menolak dengan misuse of aggregate: COUNT(). Syarat yang memakai fungsi agregat ditulis di HAVING.

Keduanya boleh dipakai bersama:

SELECT departemen, COUNT(*) AS jumlah
FROM karyawan
WHERE gaji > 6300000
GROUP BY departemen
HAVING COUNT(*) > 2;

WHERE membuang Dewi (6.000.000) dan Maya (6.200.000) dulu, jadi HR tinggal 1 orang. Setelah itu HAVING cuma meloloskan IT.

💡 Beda SQLite, MySQL, dan PostgreSQL

⚠️ Jebakan yang sering ketemu

TL;DR: GROUP BY kolom membuat satu kelompok untuk tiap nilai yang berbeda, dan fungsi agregat menghitung per kelompok: hasilnya satu baris per kelompok. WHERE menyaring baris sebelum dikelompokkan, HAVING menyaring kelompok sesudahnya, dan syarat dengan COUNT, AVG dan kawan-kawan selalu di HAVING. Kolom biasa di SELECT harus ada di GROUP BY.

Yang akan kamu pelajari