FILTER Clause di SQL untuk Agregasi Bersyarat
TL;DR
Klausa FILTER di SQL bikin fungsi agregat cuma ngitung baris yang cocok kondisi tertentu, pakai bentuk COUNT(*) FILTER (WHERE kondisi). Ini alternatif yang lebih ringkas dan lebih gampang dibaca dibanding pola SUM(CASE WHEN). FILTER didukung PostgreSQL dan SQLite modern, tapi belum ada di MySQL, jadi buat MySQL kamu tetap pakai CASE WHEN.
Klausa FILTER di SQL bikin fungsi agregat cuma ngitung baris yang cocok kondisi tertentu. Bentuknya COUNT(*) FILTER (WHERE kondisi).
Ini alternatif yang lebih bersih buat pola SUM(CASE WHEN) yang sering panjang dan susah dibaca.
Di artikel ini kamu bakal belajar sintaks FILTER, bandinginnya sama CASE WHEN, contoh nyata dari data order UMKM, plus kapan sebaiknya nggak pakai FILTER.
Apa itu klausa FILTER di SQL?
FILTER nempel di fungsi agregat biar cuma ngitung baris yang cocok kondisi. Bentuknya fungsi agregat diikuti FILTER (WHERE kondisi). Ini bikin kamu bisa naruh beberapa metrik bersyarat berdampingan dalam satu query, dengan sintaks yang lebih ringkas dari CASE WHEN.
COUNT(*) FILTER (WHERE status = 'lunas')
Baris yang statusnya bukan lunas nggak ikut kehitung. Nggak perlu CASE, nggak perlu THEN, tinggal tulis kondisinya langsung.
FILTER ini pada dasarnya cara lain buat conditional aggregation, dengan hasil yang persis sama.
Apa beda FILTER dan CASE WHEN?
Keduanya bikin agregasi bersyarat dan hasilnya identik. Bedanya di sintaks dan dukungan database. FILTER lebih pendek dan lebih jelas maksudnya, tapi cuma jalan di PostgreSQL dan SQLite modern. CASE WHEN lebih panjang tapi jalan di mana pun.
Bandingin dua versi ini yang ngitung hal yang sama:
-- Versi CASE WHEN
COUNT(CASE WHEN status = 'lunas' THEN 1 END) AS lunas
-- Versi FILTER
COUNT(*) FILTER (WHERE status = 'lunas') AS lunas
Versi FILTER lebih gampang dibaca, apalagi kalau kondisinya rumit. Waktu satu query punya lima metrik bersyarat, selisih keterbacaannya kerasa banget.
Bisakah FILTER dipakai dengan SUM dan AVG?
Bisa. FILTER jalan sama semua fungsi agregat: COUNT, SUM, AVG, MIN, dan MAX. Kamu tinggal tempel FILTER (WHERE kondisi) setelah fungsinya. Ini berguna buat ngitung total atau rata-rata dari subset data tanpa subquery terpisah.
SUM(total) FILTER (WHERE status = 'lunas') AS omzet_lunas,
AVG(total) FILTER (WHERE metode_bayar = 'qris') AS rata_qris
Baris pertama njumlahin total cuma dari order lunas. Baris kedua ngitung rata-rata nilai order cuma buat yang bayar QRIS. Semua dalam satu query.
Contoh kasus: laporan order bulanan toko_berkah
Toko_berkah punya tabel transaksi dengan kolom tanggal, status, metode_bayar, dan total. Pemilik toko mau satu laporan bulanan yang nunjukin total order, order lunas, order batal, dan omzet lunas, semua berdampingan.
SELECT
DATE_TRUNC('month', tanggal) AS bulan,
COUNT(*) AS total_order,
COUNT(*) FILTER (WHERE status = 'lunas') AS lunas,
COUNT(*) FILTER (WHERE status = 'batal') AS batal,
SUM(total) FILTER (WHERE status = 'lunas') AS omzet
FROM transaksi
GROUP BY DATE_TRUNC('month', tanggal)
ORDER BY bulan;
Dari data tiga bulan, muncul insight yang bikin pemilik toko kaget: tingkat pembatalan order naik dari 6% di bulan pertama jadi 14% di bulan ketiga. Lebih dari dua kali lipat.
Setelah ditelusuri, ternyata order batal paling banyak dari metode bayar transfer yang pelanggannya sering lupa bayar. Pemilik toko lalu mindahin default pembayaran ke QRIS, dan angka batal turun lagi bulan berikutnya.
Query yang sama pakai CASE WHEN bakal dua kali lebih panjang dan lebih capek dibaca.
Kapan sebaiknya pakai CASE WHEN daripada FILTER?
Pakai CASE WHEN kalau database kamu nggak dukung FILTER, terutama MySQL. Pakai juga CASE WHEN kalau query kamu harus jalan di beberapa jenis database sekaligus. Buat itu, CASE WHEN lebih aman karena portabel.
| Kondisi | Pilihan |
|---|---|
| Pakai PostgreSQL atau SQLite | FILTER |
| Pakai MySQL | CASE WHEN |
| Query harus portabel | CASE WHEN |
| Mau kode paling bersih | FILTER |
Buat ngerti dasar logikanya, cek glosarium CASE WHEN.
Kesalahan umum saat pakai FILTER
- Dipakai di MySQL. MySQL belum dukung FILTER, jadi query-nya bakal error sintaks. Pastiin database kamu PostgreSQL atau SQLite dulu.
- Lupa tanda kurung. Kondisinya harus di dalam FILTER (WHERE ...). Lupa kurung bikin error.
- Nyampur kondisi tumpang tindih. Kalau satu baris cocok dua FILTER berbeda, dia kehitung di dua kolom. Pastiin kategorinya saling lepas kalau memang harus eksklusif.
FAQ
Apa itu klausa FILTER di SQL?
FILTER nempel di fungsi agregat biar cuma ngitung baris yang cocok kondisi, bentuknya COUNT(*) FILTER (WHERE kondisi). Alternatif yang lebih ringkas dari SUM(CASE WHEN) buat agregasi bersyarat.
Apa beda FILTER dan CASE WHEN?
Hasilnya sama, sintaksnya beda. FILTER lebih pendek tapi cuma jalan di PostgreSQL dan SQLite. CASE WHEN lebih panjang tapi jalan di semua database.
Apakah FILTER jalan di MySQL?
Belum. Buat MySQL, pakai pola SUM(CASE WHEN) atau COUNT(CASE WHEN). FILTER didukung PostgreSQL sejak 9.4 dan SQLite sejak 3.30.
Bisakah FILTER dipakai dengan SUM?
Bisa. FILTER jalan sama COUNT, SUM, AVG, MIN, dan MAX. Contohnya SUM(total) FILTER (WHERE status = 'lunas').
Penutup
FILTER bikin agregasi bersyarat jauh lebih enak dibaca daripada CASE WHEN. Inti pakainya: fungsi agregat, lalu FILTER (WHERE kondisi).
Ingat satu batasan: FILTER belum ada di MySQL, jadi cek dulu database kamu.
Mau lanjut ke pola agregasi lain? Cek pivot dinamis di SQL dan referensi resmi di dokumentasi agregat PostgreSQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Composite Index di SQL: Cara Kerja dan Urutan Kolom
Composite index itu index atas beberapa kolom sekaligus. Urutan kolomnya nentuin query mana yang kebantu, lewat aturan leftmost prefix.
Menghitung Stickiness (DAU/MAU) di SQL
Stickiness ngukur seberapa sering user balik lagi. Ini cara hitung DAU, MAU, dan rasio stickiness pakai SQL, plus contoh aplikasi UMKM.
Menghitung DAU dan MAU dengan SQL
DAU dan MAU dua metrik wajib buat produk digital. Ini cara hitungnya pakai SQL, lengkap query DISTINCT, per bulan, sampai rasio stickiness.