Data mentah menyimpan kode, sedangkan pembaca laporan butuh keterangan: status baru perlu tampil sebagai “Menunggu pembayaran”, transaksi besar perlu ditandai “gratis kirim”, dan daftar pesanan perlu diurutkan berdasarkan prioritas kerja, bukan alfabetis. Semua keputusan semacam itu bisa diambil di dalam query lewat fungsi kondisional — IF() untuk pilihan cepat dua cabang, dan CASE WHEN untuk logika bertingkat yang bisa menempel di hampir semua bagian SELECT. Pada chapter ini kita memakai tabel pesanan kecil untuk melatih kedua bentuk CASE, posisi CASE di daftar kolom maupun di ORDER BY, lalu menutup dengan peta perbandingan IF, IFNULL, dan NULLIF.
Menyiapkan Tabel Latihan #
DROP DATABASE IF EXISTS belajar_fungsi;
CREATE DATABASE belajar_fungsi;
USE belajar_fungsi;Output yang Dihasilkan:
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Database changedCREATE TABLE pesanan (
id INT AUTO_INCREMENT PRIMARY KEY,
produk VARCHAR(50) NOT NULL,
status VARCHAR(20) NOT NULL,
total DECIMAL(10,2) NOT NULL
);
INSERT INTO pesanan (produk, status, total) VALUES
('Buku Tulis', 'selesai', 45000.00),
('Pensil 2B', 'baru', 12000.00),
('Kertas A4', 'diproses', 250000.00),
('Stipo', 'baru', 18000.00),
('Penghapus', 'selesai', 7500.00),
('Rautan', 'diproses', 9500.00);Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0Kolom status berisi tiga kode: baru, diproses, dan selesai. Kolom total menyimpan nilai transaksi yang akan kita pakai untuk menguji kondisi numerik. Enam baris ini cukup untuk memperlihatkan setiap cabang kondisi yang kita tulis.
Fungsi IF dengan Tiga Argumen #
IF(kondisi, nilai_jika_benar, nilai_jika_salah) meniru operator ternary di bahasa pemrograman:
SELECT IF(3 > 2, 'benar', 'salah') AS jika_benar,
IF(3 < 2, 'benar', 'salah') AS jika_salah,
IF(NULL, 'benar', 'salah') AS jika_null;Output yang Dihasilkan:
+------------+------------+-----------+
| jika_benar | jika_salah | jika_null |
+------------+------------+-----------+
| benar | salah | salah |
+------------+------------+-----------+
1 row in set (0.00 sec)Dua contoh pertama sederhana; contoh ketiga menunjukkan aturan khusus: kondisi yang bernilai NULL diperlakukan salah, sehingga IF mengembalikan argumen ketiganya. Penerapan pada tabel — transaksi di atas 100000 gratis ongkir:
SELECT produk, total,
IF(total >= 100000, 'gratis kirim', 'bayar kirim') AS ongkir
FROM pesanan
ORDER BY id;Output yang Dihasilkan:
+------------+-----------+--------------+
| produk | total | ongkir |
+------------+-----------+--------------+
| Buku Tulis | 45000.00 | bayar kirim |
| Pensil 2B | 12000.00 | bayar kirim |
| Kertas A4 | 250000.00 | gratis kirim |
| Stipo | 18000.00 | bayar kirim |
| Penghapus | 7500.00 | bayar kirim |
| Rautan | 9500.00 | bayar kirim |
+------------+-----------+--------------+
6 rows in set (0.00 sec)Fungsi IF cocok ketika keputusannya memang dua cabang. Begitu jumlah cabangnya bertambah, deretan IF bersarang menjadi sulit dibaca — di titik itu kita beralih ke CASE.
Searched CASE: Kondisi Bebas di Setiap Cabang #
Bentuk pertama CASE — disebut searched CASE — menuliskan kondisi lengkap di setiap WHEN:
SELECT produk, total,
CASE
WHEN total >= 100000 THEN 'besar'
WHEN total >= 20000 THEN 'sedang'
ELSE 'kecil'
END AS ukuran
FROM pesanan
ORDER BY id;Output yang Dihasilkan:
+------------+-----------+--------+
| produk | total | ukuran |
+------------+-----------+--------+
| Buku Tulis | 45000.00 | sedang |
| Pensil 2B | 12000.00 | kecil |
| Kertas A4 | 250000.00 | besar |
| Stipo | 18000.00 | kecil |
| Penghapus | 7500.00 | kecil |
| Rautan | 9500.00 | kecil |
+------------+-----------+--------+
6 rows in set (0.00 sec)Mari kita bedah strukturnya baris per baris:
CASEmembuka ekspresi; ekspresi ini akan menghasilkan satu nilai per baris.WHEN total >= 100000 THEN 'besar'diuji lebih dulu — kondisi yang benar lebih awal langsung menang, danKertas A4(250000) berhenti di cabang pertama.WHEN total >= 20000 THEN 'sedang'hanya diuji bila cabang pertama gagal — karena ituBuku Tulis(45000) tidak ikut “besar” walau lolos syarat cabang kedua.ELSE 'kecil'menampung baris yang gagal semua kondisi.ENDmenutup ekspresi, danAS ukuranmemberi nama kolom hasilnya di daftarSELECT.
Urutan WHEN menentukan hasilnya: syarat yang lebih ketat harus ditulis lebih awal. Bila kita menukar dua kondisi di atas, seluruh transaksi di atas 20000 akan berhenti di cabang sedang dan tidak ada yang berpeluang menjadi besar.
Bukti perilakunya bisa kita lihat langsung dengan menghapus ELSE:
SELECT produk,
CASE WHEN total >= 20000 THEN 'utama' END AS ditandai
FROM pesanan
ORDER BY id;Output yang Dihasilkan:
+------------+----------+
| produk | ditandai |
+------------+----------+
| Buku Tulis | utama |
| Pensil 2B | NULL |
| Kertas A4 | utama |
| Stipo | NULL |
| Penghapus | NULL |
| Rautan | NULL |
+------------+----------+
6 rows in set (0.00 sec)Hanya dua transaksi bernilai utama; empat baris lainnya menampilkan NULL karena tidak ada ELSE yang menampungnya.
Simple CASE: Menguji Kesetaraan Satu Nilai #
Bentuk kedua — simple CASE — menuliskan satu ekspresi setelah CASE, lalu setiap WHEN membandingkan nilai secara kesetaraan:
SELECT produk, status,
CASE status
WHEN 'baru' THEN 'Menunggu pembayaran'
WHEN 'diproses' THEN 'Sedang dikemas'
ELSE 'Sudah sampai'
END AS keterangan
FROM pesanan
ORDER BY id;Output yang Dihasilkan:
+------------+----------+---------------------+
| produk | status | keterangan |
+------------+----------+---------------------+
| Buku Tulis | selesai | Sudah sampai |
| Pensil 2B | baru | Menunggu pembayaran |
| Kertas A4 | diproses | Sedang dikemas |
| Stipo | baru | Menunggu pembayaran |
| Penghapus | selesai | Sudah sampai |
| Rautan | diproses | Sedang dikemas |
+------------+----------+---------------------+
6 rows in set (0.00 sec)Ekspresi CASE status WHEN 'baru' ... adalah kependekan dari CASE WHEN status = 'baru' .... Bentuk simple pas untuk pemetaan kode ke label seperti ini; bentuk searched lebih tepat ketika setiap cabang menguji kondisi yang berbeda-beda (rentang harga, kombinasi kolom, atau pembanding campuran). Kedua bentuk menghasilkan kolom baru di daftar SELECT dengan alias seperti biasa — keterangan — tanpa mengubah data tabel.
CASE di ORDER BY: Urutan Berdasarkan Prioritas #
Ekspresi CASE tidak terbatas di daftar kolom — ia juga bisa dipasang di ORDER BY. Kebutuhan klasiknya: tampilkan pesanan baru paling atas, diproses di tengah, selesai di bawah, dan di dalam tiap kelompok urutkan berdasarkan nama produk:
SELECT produk, status
FROM pesanan
ORDER BY CASE status
WHEN 'baru' THEN 1
WHEN 'diproses' THEN 2
ELSE 3
END,
produk;Output yang Dihasilkan:
+------------+----------+
| produk | status |
+------------+----------+
| Pensil 2B | baru |
| Stipo | baru |
| Kertas A4 | diproses |
| Rautan | diproses |
| Buku Tulis | selesai |
| Penghapus | selesai |
+------------+----------+
6 rows in set (0.00 sec)CASE di ORDER BY dievaluasi untuk setiap baris menjadi angka prioritas 1, 2, atau 3, lalu angka itu menjadi kunci urutan pertama; kolom produk menjadi kunci kedua. Hasilnya deterministik dan mudah dibaca: dua pesanan baru di urutan atas, disusul dua diproses, lalu dua selesai. Trik ini mengisi celah yang tidak bisa digantikan ORDER BY status biasa, karena urutan alfabetis baru-diproses-selesai hampir tidak pernah sama dengan urutan prioritas kerja kita.
Peta IF, IFNULL, dan NULLIF #
Tiga fungsi ini sering tertukar karena namanya mirip, padahal perannya berbeda:
| Fungsi | Menguji apa | Mengembalikan |
|---|---|---|
IF(kondisi, a, b) | kondisi logika apa pun | a bila benar, b bila salah |
IFNULL(v, ganti) | nilai v adalah NULL | ganti bila v NULL, selain itu v |
NULLIF(a, b) | kesetaraan a = b | NULL bila sama, selain itu a |
IFNULL sebenarnya kependekan dari IF(v IS NULL, ganti, v) — keduanya bisa dipertukarkan, tetapi IFNULL jauh lebih jelas maksudnya:
SELECT IFNULL(NULL, 'nilai pengganti') AS via_ifnull,
IF(NULL IS NULL, 'nilai pengganti', NULL) AS via_if;Output yang Dihasilkan:
+-----------------+-----------------+
| via_ifnull | via_if |
+-----------------+-----------------+
| nilai pengganti | nilai pengganti |
+-----------------+-----------------+
1 row in set (0.00 sec)Kedua kolom menghasilkan nilai yang sama. Pilih IFNULL untuk penggantian NULL, pilih IF untuk kondisi umum, dan pakai NULLIF ketika justru ingin menghasilkan NULL pada kecocokan — misalnya mengamankan pembagian dari pembagi nol seperti yang kita latih di chapter Fungsi NULL.
Membersihkan Database Latihan #
DROP DATABASE belajar_fungsi;Output yang Dihasilkan:
Query OK, 1 row affected (0.00 sec)Kita kini bisa mengemas logika keputusan langsung ke dalam query — dua cabang dengan IF, bertingkat dengan CASE, sampai urutan tampilan custom di ORDER BY. Chapter berikutnya melihat ke arah yang berbeda: bagaimana satu query meringkas seluruh tabel menjadi satu baris angka dengan SUM, AVG, MIN, MAX, dan COUNT.