Ketika menganalisis data di MySQL, Anda sering perlu mengelompokkan data berdasarkan kriteria tertentu, lalu melakukan perhitungan terhadap setiap kelompok. Misalnya, menghitung total penjualan per kategori, menghitung rata-rata gaji per departemen, atau menemukan jumlah pelanggan per kota. Dua klausa yang menjadi kunci untuk kebutuhan ini adalah GROUP BY dan HAVING. Mari kita pelajari keduanya secara mendalam.
Apa Itu GROUP BY?
GROUP BY adalah klausa SQL yang digunakan untuk mengelompokkan baris-baris yang memiliki nilai sama pada kolom tertentu menjadi satu baris ringkasan. GROUP BY biasanya dikombinasikan dengan fungsi agregasi seperti COUNT(), SUM(), AVG(), MIN(), dan MAX().
Persiapan Data Contoh
CREATE TABLE penjualan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_produk VARCHAR(100) NOT NULL,
kategori VARCHAR(50) NOT NULL,
jumlah INT NOT NULL,
harga_satuan DECIMAL(10, 2) NOT NULL,
tanggal DATE NOT NULL
) ENGINE=InnoDB;
INSERT INTO penjualan (nama_produk, kategori, jumlah, harga_satuan, tanggal) VALUES
('Laptop ASUS', 'Elektronik', 2, 8500000, '2024-01-05'),
('Mouse Logitech', 'Elektronik', 10, 350000, '2024-01-06'),
('Buku Python', 'Buku', 5, 120000, '2024-01-07'),
('Keyboard Mechanical', 'Elektronik', 3, 750000, '2024-01-08'),
('Buku MySQL', 'Buku', 8, 95000, '2024-01-09'),
('Meja Kerja', 'Furnitur', 1, 2500000, '2024-01-10'),
('Kursi Ergonomis', 'Furnitur', 2, 3200000, '2024-01-11'),
('Monitor 27 Inch', 'Elektronik', 1, 4500000, '2024-01-12'),
('Buku Laravel', 'Buku', 12, 110000, '2024-01-13'),
('Lemari Arsip', 'Furnitur', 1, 1800000, '2024-01-14');
Penggunaan Dasar GROUP BY
Menghitung jumlah produk dan total pendapatan per kategori:
-- Hitung total penjualan per kategori
SELECT
kategori,
COUNT(*) AS jumlah_transaksi,
SUM(jumlah) AS total_unit_terjual,
SUM(jumlah * harga_satuan) AS total_pendapatan,
AVG(harga_satuan) AS rata_rata_harga
FROM penjualan
GROUP BY kategori
ORDER BY total_pendapatan DESC;
GROUP BY dengan Beberapa Kolom
Anda bisa mengelompokkan berdasarkan lebih dari satu kolom sekaligus:
-- Kelompokkan berdasarkan kategori dan bulan
SELECT
kategori,
MONTH(tanggal) AS bulan,
YEAR(tanggal) AS tahun,
SUM(jumlah * harga_satuan) AS total_pendapatan
FROM penjualan
GROUP BY kategori, YEAR(tanggal), MONTH(tanggal)
ORDER BY tahun, bulan, kategori;
Apa Itu HAVING?
HAVING adalah klausa yang digunakan untuk memfilter hasil GROUP BY. Fungsinya mirip dengan WHERE, namun perbedaan utamanya adalah:
- WHERE: Memfilter baris sebelum dikelompokkan dan tidak bisa menggunakan fungsi agregasi.
- HAVING: Memfilter hasil setelah dikelompokkan dan bisa menggunakan fungsi agregasi.
Penggunaan HAVING
Tampilkan hanya kategori dengan total pendapatan di atas 5 juta:
-- Filter grup menggunakan HAVING
SELECT
kategori,
SUM(jumlah * harga_satuan) AS total_pendapatan
FROM penjualan
GROUP BY kategori
HAVING total_pendapatan > 5000000
ORDER BY total_pendapatan DESC;
Kombinasi WHERE dan HAVING
WHERE dan HAVING bisa digunakan bersamaan. WHERE memfilter data mentah terlebih dahulu, baru HAVING memfilter hasil agregasi:
-- WHERE filter data dulu, HAVING filter hasil grup
SELECT
kategori,
COUNT(*) AS jumlah_produk,
SUM(jumlah * harga_satuan) AS total_pendapatan
FROM penjualan
WHERE tanggal >= '2024-01-07' -- filter tanggal dulu
GROUP BY kategori
HAVING jumlah_produk >= 2 -- filter hasil grup
ORDER BY total_pendapatan DESC;
Fungsi Agregasi yang Sering Dipakai
COUNT(*): Menghitung jumlah baris dalam setiap grup.COUNT(kolom): Menghitung baris yang nilainya tidak NULL.SUM(kolom): Menjumlahkan nilai dalam kolom.AVG(kolom): Menghitung rata-rata nilai kolom.MAX(kolom): Mengambil nilai terbesar dalam grup.MIN(kolom): Mengambil nilai terkecil dalam grup.
-- Semua fungsi agregasi sekaligus
SELECT
kategori,
COUNT(*) AS jumlah_item,
SUM(jumlah) AS total_unit,
ROUND(AVG(harga_satuan), 2) AS rata_harga,
MAX(harga_satuan) AS harga_tertinggi,
MIN(harga_satuan) AS harga_terendah
FROM penjualan
GROUP BY kategori;
GROUP BY dengan ROLLUP
MySQL 8 mendukung WITH ROLLUP untuk menambahkan baris subtotal dan grand total secara otomatis:
-- Tambahkan baris total keseluruhan dengan ROLLUP
SELECT
COALESCE(kategori, 'TOTAL KESELURUHAN') AS kategori,
SUM(jumlah * harga_satuan) AS total_pendapatan
FROM penjualan
GROUP BY kategori WITH ROLLUP;
Urutan Eksekusi Query SQL
Penting untuk memahami urutan eksekusi klausa SQL agar tidak bingung menggunakan WHERE vs HAVING:
- FROM โ tentukan tabel sumber
- WHERE โ filter baris individual
- GROUP BY โ kelompokkan baris
- HAVING โ filter grup
- SELECT โ pilih kolom yang ditampilkan
- ORDER BY โ urutkan hasil
- LIMIT โ batasi jumlah baris
Kesimpulan
GROUP BY dan HAVING adalah dua klausa yang saling melengkapi dalam MySQL. GROUP BY mengelompokkan data berdasarkan nilai kolom tertentu, sementara HAVING memfilter hasil pengelompokan berdasarkan kondisi agregasi. Kunci perbedaannya: gunakan WHERE untuk memfilter data sebelum dikelompokkan, dan gunakan HAVING untuk memfilter setelah dikelompokkan. Kuasai kedua klausa ini dan Anda akan mampu menghasilkan laporan analitik yang powerful langsung dari query SQL.