Pernahkah Anda ingin menghitung “berapa transaksi yang berstatus lunas” dan “berapa yang belum lunas” dalam satu query, tanpa harus menjalankan dua perintah SELECT COUNT terpisah? Atau menjumlahkan hanya nilai penjualan yang di atas satu juta? Teknik ini disebut agregasi kondisional — sering diistilahkan sebagai COUNT IF dan SUM IF.
MySQL tidak punya fungsi bernama COUNTIF seperti di Excel, tetapi hasil yang sama bisa dicapai dengan mengombinasikan SUM() atau COUNT() dengan ekspresi CASE WHEN atau fungsi IF(). Mari kita kupas satu per satu.

Tabel Contoh
CREATE TABLE transaksi (
id INT PRIMARY KEY AUTO_INCREMENT,
pelanggan VARCHAR(50),
status ENUM('lunas','pending','batal'),
metode VARCHAR(20),
nominal INT
);
INSERT INTO transaksi (pelanggan, status, metode, nominal) VALUES
('Rani', 'lunas', 'transfer', 1500000),
('Dimas', 'pending', 'cod', 750000),
('Sari', 'lunas', 'cod', 300000),
('Bagas', 'batal', 'transfer', 900000),
('Nadia', 'lunas', 'transfer', 2100000);
Konsep Dasar: CASE WHEN sebagai Saklar
Kunci agregasi kondisional adalah ekspresi CASE WHEN kondisi THEN nilai ELSE nilai_lain END. Ekspresi ini mengevaluasi setiap baris dan mengembalikan nilai berbeda tergantung kondisi. Ketika dibungkus SUM() atau COUNT(), hasilnya menjadi ringkasan berdasar syarat.
COUNT IF: Menghitung Baris dengan Syarat
Untuk menghitung berapa transaksi yang berstatus lunas, kita hitung baris yang memenuhi syarat saja. Ada dua gaya penulisan yang umum.
Gaya 1 — SUM(CASE WHEN …): memberi angka 1 untuk baris yang cocok, lalu dijumlahkan.
SELECT
SUM(CASE WHEN status = 'lunas' THEN 1 ELSE 0 END) AS jml_lunas,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS jml_pending,
SUM(CASE WHEN status = 'batal' THEN 1 ELSE 0 END) AS jml_batal
FROM transaksi;
Hasil: jml_lunas = 3, jml_pending = 1, jml_batal = 1 — semuanya dalam satu baris.
Gaya 2 — COUNT(CASE WHEN …): memanfaatkan sifat COUNT() yang mengabaikan NULL. Baris yang tidak cocok kita buat menjadi NULL agar tidak terhitung.
SELECT
COUNT(CASE WHEN status = 'lunas' THEN 1 END) AS jml_lunas,
COUNT(CASE WHEN metode = 'cod' THEN 1 END) AS jml_cod
FROM transaksi;
Perhatikan tidak ada ELSE — artinya baris yang tidak cocok bernilai NULL dan otomatis diabaikan COUNT().
Trik Singkat: SUM(kondisi)
Di MySQL, ekspresi perbandingan menghasilkan angka 1 (benar) atau 0 (salah). Karena itu kita bisa menyingkat penulisan tanpa CASE sama sekali:
SELECT
SUM(status = 'lunas') AS jml_lunas,
SUM(nominal > 1000000) AS jml_transaksi_besar
FROM transaksi;
Cara ini paling ringkas dan populer di kalangan praktisi MySQL. Namun perlu diingat, ini spesifik MySQL/MariaDB — di database lain seperti PostgreSQL, penulisan CASE WHEN lebih portabel.
SUM IF: Menjumlahkan Nilai dengan Syarat
Kalau COUNT IF menghitung jumlah baris, SUM IF menjumlahkan nilai kolom tertentu yang memenuhi syarat. Misalnya, total pemasukan hanya dari transaksi lunas:
SELECT
SUM(CASE WHEN status = 'lunas' THEN nominal ELSE 0 END) AS pendapatan_riil,
SUM(CASE WHEN status = 'pending' THEN nominal ELSE 0 END) AS potensi_pending
FROM transaksi;
Hasil: pendapatan_riil = 3.900.000 (1.500.000 + 300.000 + 2.100.000) dan potensi_pending = 750.000. Bandingkan betapa repotnya jika harus dua query terpisah lalu digabung di aplikasi.
Menggunakan Fungsi IF()
MySQL juga menyediakan fungsi IF(kondisi, nilai_benar, nilai_salah) yang lebih ringkas daripada CASE untuk kondisi tunggal:
SELECT
SUM(IF(metode = 'transfer', nominal, 0)) AS via_transfer,
SUM(IF(metode = 'cod', nominal, 0)) AS via_cod
FROM transaksi;
Dikombinasikan dengan GROUP BY
Agregasi kondisional makin bertenaga bila dipadu GROUP BY. Contoh: rekap jumlah dan nilai transaksi lunas per metode pembayaran.
SELECT
metode,
COUNT(*) AS total_transaksi,
SUM(status = 'lunas') AS jml_lunas,
SUM(IF(status = 'lunas', nominal, 0)) AS nilai_lunas
FROM transaksi
GROUP BY metode;
Contoh Kasus Nyata: Dashboard Ringkasan Order
Misalkan Anda membangun dashboard admin yang menampilkan tiga kartu: total order, order selesai, dan nilai penjualan bulan ini. Alih-alih tiga query, satu query cukup:
SELECT
COUNT(*) AS total_order,
SUM(status = 'lunas') AS order_selesai,
SUM(IF(status = 'lunas', nominal, 0)) AS omzet
FROM transaksi
WHERE MONTH(created_at) = MONTH(CURDATE())
AND YEAR(created_at) = YEAR(CURDATE());
Satu kali eksekusi menghasilkan seluruh angka yang dibutuhkan dashboard — lebih cepat, lebih hemat, dan lebih mudah dirawat.
Penutup
Agregasi kondisional adalah salah satu teknik SQL yang paling sering menyelamatkan pekerjaan pelaporan. Ingat tiga polanya: SUM(CASE WHEN ... THEN 1 ELSE 0 END) untuk menghitung, SUM(CASE WHEN ... THEN kolom ELSE 0 END) untuk menjumlahkan, dan trik singkat SUM(kondisi) khas MySQL. Kuasai ketiganya dan laporan multi-angka Anda cukup satu query saja.
Referensi: untuk pendalaman lebih lanjut, kunjungi dokumentasi resmi MySQL.

