GROUP BY dan Fungsi Agregasi di SQL: Dua hal yang sering muncul
Kalau mau mulai belajar SQL, ada satu titik di mana query yang tadinya cuma SELECT * FROM tabel berubah jadi ribet karena harus ngerangkum ratusan bahkan ribuan baris jadi beberapa angka aja. Nah, di situlah GROUP BY dan fungsi agregasi mulai kepake. Dua hal ini nyaris selalu jalan berdampingan, dan begitu kamu paham logikanya, banyak query yang tadinya bikin bingung jadi kelihatan masuk akal.
Artikel ini bakal ngebahas ketiga fungsi agregasi yang paling sering dipakai COUNT, SUM, AVG dan gimana GROUP BY jadi “lem” yang bikin fungsi-fungsi itu bisa mengelompokkan data sesuai kategori yang kita mau.
Masalah yang Coba Diselesaikan
Bayangin ada tabel penjualan dengan kolom produk, jumlah, dan harga. Kalau cuma mau tahu total penjualan semua baris, gampang — tinggal SUM(jumlah). Tapi kalau pertanyaannya “berapa total penjualan per produk?”, nah di sini SUM aja nggak cukup. Kamu butuh cara buat bilang ke database: “kelompokkan dulu baris-barisnya berdasarkan produk, baru jumlahkan masing-masing kelompok.” Itulah kerjaan GROUP BY.
Jadi kalau mau disederhanain, fungsi agregasi itu ngitung, sementara GROUP BY itu yang nentuin batas-batas kelompok mana yang harus diitung terpisah.
COUNT — Ngitung Jumlah Baris
COUNT ini yang paling sering dipakai karena paling gampang dipahami. Fungsinya buat menghitung berapa banyak baris yang ada dalam suatu kelompok.
SELECT produk, COUNT(*) AS jumlah_transaksi
FROM penjualan
GROUP BY produk;
Query di atas bakal ngasih tahu berapa kali setiap produk itu muncul di tabel transaksi. Satu hal yang sering bikin orang salah kaprah: COUNT(*) beda sama COUNT(nama_kolom). COUNT(*) menghitung semua baris tanpa peduli isinya NULL atau nggak, sedangkan COUNT(nama_kolom) cuma menghitung baris yang kolom tersebut nilainya nggak NULL. Jadi kalau ada data yang bolong, hasilnya bisa beda, dan ini sering jadi sumber bug yang bikin orang garuk-garuk kepala pas angka laporan nggak sesuai ekspektasi.
SUM — Menjumlah Nilai
SUM dipakai kalau kamu butuh total dari suatu kolom numerik. Masih pakai contoh tabel penjualan tadi:
SELECT produk, SUM(jumlah) AS total_terjual
FROM penjualan
GROUP BY produk;
Ini ngasih total unit yang terjual buat setiap produk. Yang perlu diinget, SUM cuma jalan buat kolom angka kalau dipaksa ke kolom teks, ya bakal error. Kadang orang juga lupa kalau SUM otomatis mengabaikan NULL, jadi kalau ada baris yang datanya kosong, itu nggak dianggap nol, tapi memang di-skip dari perhitungan.
AVG — Menghitung Rata-Rata
AVG itu rata-rata biasa, total dibagi jumlah baris yang punya nilai (bukan dibagi semua baris termasuk yang NULL).
SELECT produk, AVG(harga) AS rata_rata_harga
FROM penjualan
GROUP BY produk;
Satu hal yang sering luput: AVG itu sensitif banget sama outlier. Kalau ada satu transaksi yang harganya ekstrem entah salah input atau memang transaksi besar — rata-ratanya bisa langsung melenceng jauh dari gambaran yang sebenarnya. Makanya kadang lebih aman ngecek juga MIN dan MAX di samping AVG, biar tahu rentang datanya kayak apa sebelum percaya begitu aja sama angka rata-rata.
Kenapa Harus Ada GROUP BY?
Aturan dasarnya gini: setiap kolom yang muncul di SELECT tapi bukan bagian dari fungsi agregasi, itu harus disebutkan di GROUP BY. Kalau nggak, database bakal bingung — atau di beberapa sistem malah dikasih error langsung.
Contoh yang salah:
SELECT produk, kategori, SUM(jumlah)
FROM penjualan
GROUP BY produk;
Query ini bermasalah karena kategori ikut nongol di SELECT tapi nggak ada di GROUP BY. Database nggak tahu harus ambil kategori yang mana kalau dalam satu grup produk ternyata ada beberapa kategori berbeda. Perbaikannya, tinggal tambahin kategori ke GROUP BY juga:
SELECT produk, kategori, SUM(jumlah)
FROM penjualan
GROUP BY produk, kategori;
Dengan begini, data dikelompokkan berdasarkan kombinasi produk dan kategori sekaligus.
HAVING vs WHERE — Ini yang Sering Ketuker
Ini salah satu kebingungan klasik. WHERE dipakai buat nyaring baris sebelum dikelompokkan, sedangkan HAVING dipakai buat nyaring hasil setelah dikelompokkan dan diagregasi.
SELECT produk, SUM(jumlah) AS total_terjual
FROM penjualan
WHERE tanggal >= '2026-01-01'
GROUP BY produk
HAVING SUM(jumlah) > 100;
Di query itu, WHERE nyaring transaksi yang tanggalnya dari awal tahun 2026, baru setelah itu data dikelompokkan per produk dan dijumlahkan. HAVING baru masuk belakangan buat nyaring produk mana aja yang total terjualnya di atas 100 unit. Kalau kamu coba pakai SUM(jumlah) > 100 di dalam WHERE, itu bakal error, karena pas WHERE dieksekusi, agregasi belum kejadian sama sekali.
Contoh yang Menggabungkan Semuanya
Biar kebayang gimana ketiganya kepake bareng dalam satu query yang lebih realistis:
SELECT
produk,
COUNT(*) AS jumlah_transaksi,
SUM(jumlah) AS total_unit,
AVG(harga) AS rata_rata_harga
FROM penjualan
WHERE tanggal BETWEEN '2026-01-01' AND '2026-06-30'
GROUP BY produk
HAVING COUNT(*) >= 5
ORDER BY total_unit DESC;
Query ini nyari, untuk setiap produk di semester pertama 2026: ada berapa transaksi, berapa total unit yang terjual, dan berapa rata-rata harganya tapi cuma buat produk yang transaksinya minimal 5 kali, terus diurutkan dari yang penjualannya paling tinggi. Ini pola yang bakal sering banget kamu temuin di laporan bisnis sehari-hari, entah itu laporan penjualan, laporan performa cabang, atau dashboard apa pun yang butuh ringkasan per kategori.
Beberapa Hal yang Sering Bikin Keliru
Ada beberapa kesalahan yang hampir semua orang pernah lakuin waktu pertama kali belajar ini:
Nge-GROUP BY kolom yang salah, misalnya lupa masukin semua kolom non-agregat ke GROUP BY, terus bingung kenapa querynya error atau hasilnya aneh.
Ngira COUNT(kolom) sama aja dengan COUNT(*), padahal beda kalau kolomnya ada NULL.
Nyoba pakai fungsi agregasi langsung di WHERE, padahal harusnya di HAVING.
Lupa kalau AVG bisa menyesatkan kalau datanya nggak merata atau ada outlier yang ekstrem.
Penutup
Intinya, GROUP BY dan fungsi agregasi itu pasangan yang saling melengkapi — GROUP BY nentuin batas kelompoknya, fungsi agregasi yang ngitung isinya. Begitu logika ini udah nempel di kepala, kamu bakal lebih gampang baca dan nulis query buat kebutuhan laporan, analisis, atau dashboard apa pun. Yang penting emang latihan langsung ke data nyata, karena error-error kecil kayak lupa masukin kolom ke GROUP BY itu justru paling cepat nempel diingatan kalau udah pernah ketemu langsung.
