Foto oleh Myburgh Roux via Pexels

CASE WHEN adalah cara SQL Server menangani logika kondisional di dalam query, mirip seperti if-else pada bahasa pemrograman. Fitur ini sangat berguna untuk mengkategorikan data, membuat kolom turunan, atau bahkan membangun laporan ringkas tanpa harus mengolahnya di sisi aplikasi terlebih dahulu.

Artikel ini membahas penggunaan CASE WHEN pada SELECT, ORDER BY, dan agregasi, lengkap dengan pola conditional aggregation yang sering dipakai untuk membuat laporan pivot sederhana.

Sintaks Dasar CASE WHEN

Mengkategorikan nilai transaksi

SELECT OrderId, TotalAmount, CASE WHEN TotalAmount >= 1000000 THEN 'Besar' WHEN TotalAmount >= 500000 THEN 'Menengah' ELSE 'Kecil' END AS KategoriTransaksi FROM Orders; -- Expected: TotalAmount 1200000 -> 'Besar' -- TotalAmount 700000 -> 'Menengah' -- TotalAmount 200000 -> 'Kecil'

SQL Server mengevaluasi kondisi WHEN secara berurutan dari atas ke bawah dan berhenti pada kondisi pertama yang terpenuhi, sehingga urutan penulisan kondisi sangat memengaruhi hasil akhir. Menulis kondisi dari yang paling spesifik/besar ke yang paling umum adalah praktik yang aman.

CASE WHEN untuk Mengubah Urutan Sort

Mengurutkan status sesuai prioritas bisnis, bukan abjad

SELECT OrderId, Status FROM Orders ORDER BY CASE Status WHEN 'Pending' THEN 1 WHEN 'Shipped' THEN 2 WHEN 'Delivered' THEN 3 ELSE 4 END; -- Expected: baris dengan Status='Pending' muncul di atas, -- bukan terurut alfabetis seperti ORDER BY Status biasa

CASE WHEN di Dalam Agregasi

Pola pivot sederhana menggunakan CASE WHEN dan SUM

SELECT SUM(CASE WHEN Status = 'Delivered' THEN TotalAmount ELSE 0 END) AS TotalSukses, SUM(CASE WHEN Status = 'Cancelled' THEN TotalAmount ELSE 0 END) AS TotalBatal FROM Orders; -- Expected: dua kolom ringkasan dalam SATU baris, -- tanpa perlu dua query terpisah atau GROUP BY

Pola ini sering disebut conditional aggregation dan banyak dipakai untuk membuat laporan ringkas dalam satu baris tanpa perlu PIVOT, terutama ketika jumlah kategori yang ingin ditampilkan sebagai kolom sudah diketahui sebelumnya.

CASE WHEN dengan Kondisi Majemuk

CASE WHEN bisa menggabungkan beberapa kondisi sekaligus per cabang

SELECT CustomerId, CASE WHEN TotalAmount > 1000000 AND Status = 'Delivered' THEN 'VIP Sukses' WHEN TotalAmount > 1000000 THEN 'VIP Belum Selesai' ELSE 'Reguler' END AS Segmentasi FROM Orders;

Kondisi di dalam satu cabang WHEN bisa berupa ekspresi majemuk menggunakan AND/OR, memberikan fleksibilitas besar untuk logika bisnis yang cukup kompleks tanpa harus memecahnya menjadi banyak query terpisah.

CASE WHEN Sederhana Tanpa Kondisi Perbandingan

Selain bentuk CASE WHEN dengan kondisi perbandingan, SQL Server juga mendukung bentuk sederhana yang membandingkan satu ekspresi dengan beberapa nilai tetap, mirip seperti switch-case pada bahasa pemrograman.

CASE sederhana berbasis satu kolom

SELECT OrderId, CASE Status WHEN 'P' THEN 'Pending' WHEN 'S' THEN 'Shipped' ELSE 'Tidak Diketahui' END AS StatusLabel FROM Orders; -- Expected: kode singkat P/S diterjemahkan jadi label yang mudah dibaca

Bentuk ini lebih ringkas ditulis dibanding CASE WHEN dengan perbandingan eksplisit, namun hanya cocok ketika perbandingan yang dilakukan adalah kesetaraan sederhana, bukan rentang nilai atau kondisi majemuk.

Baik bentuk CASE WHEN dengan kondisi perbandingan maupun bentuk sederhana berbasis kesetaraan nilai, keduanya tetap dievaluasi secara berurutan dari atas ke bawah, sehingga prinsip menulis kondisi paling spesifik terlebih dahulu tetap berlaku pada kedua variasi tersebut.

CASE WHEN Sederhana vs CASE WHEN Terstruktur (Searched CASE)

Simple CASE untuk pencocokan nilai, Searched CASE untuk kondisi bebas

-- Simple CASE: membandingkan satu kolom dengan nilai tetap SELECT ProductName, CASE Category WHEN 'Elektronik' THEN 'Kategori A' WHEN 'Pakaian' THEN 'Kategori B' ELSE 'Kategori Lainnya' END AS KelompokKategori FROM Products; -- Searched CASE: mendukung kondisi kompleks per baris SELECT OrderID, TotalAmount, CASE WHEN TotalAmount >= 1000000 THEN 'Premium' WHEN TotalAmount >= 500000 THEN 'Reguler' ELSE 'Kecil' END AS SegmenPesanan FROM Orders;

SQL Server mendukung dua bentuk CASE: simple CASE yang membandingkan satu ekspresi tunggal dengan sejumlah nilai tetap menggunakan WHEN nilai THEN hasil, dan searched CASE yang setiap klausa WHEN-nya bisa berisi kondisi boolean bebas seperti perbandingan rentang atau kombinasi AND/OR. Simple CASE lebih ringkas untuk pencocokan nilai persis, sementara searched CASE diperlukan ketika logikanya melibatkan rentang angka atau beberapa kolom sekaligus.

Klausa ELSE bersifat opsional, namun tanpa ELSE, baris yang tidak cocok dengan kondisi WHEN mana pun akan menghasilkan NULL pada kolom tersebut, bukan error; kebiasaan selalu menyertakan ELSE secara eksplisit membuat maksud penanganan kasus di luar dugaan menjadi lebih jelas dan mengurangi risiko NULL yang tidak disengaja menyebar ke perhitungan berikutnya.

CASE WHEN juga dapat diletakkan di dalam fungsi agregat untuk melakukan pivot sederhana, misalnya SUM(CASE WHEN Status = 'Completed' THEN TotalAmount ELSE 0 END) untuk menjumlahkan hanya pesanan yang berstatus selesai dalam satu kolom, sebuah pola yang sangat umum dipakai untuk membuat laporan ringkasan tanpa perlu menulis query terpisah untuk tiap kondisi.

Menggunakan CASE WHEN pada Klausa ORDER BY dan GROUP BY

CASE WHEN sebagai pengurutan kustom dan pengelompokan bucket

-- CASE WHEN pada ORDER BY untuk membuat urutan kustom SELECT NamaPesanan, StatusPesanan FROM dbo.Pesanan ORDER BY CASE StatusPesanan WHEN 'Mendesak' THEN 1 WHEN 'Pending' THEN 2 WHEN 'Selesai' THEN 3 ELSE 4 END ASC; -- CASE WHEN pada GROUP BY untuk mengelompokkan ke dalam kategori/bucket SELECT CASE WHEN Umur < 18 THEN 'Anak' WHEN Umur BETWEEN 18 AND 59 THEN 'Dewasa' ELSE 'Lansia' END AS KategoriUsia, COUNT(*) AS JumlahPelanggan FROM dbo.Pelanggan GROUP BY CASE WHEN Umur < 18 THEN 'Anak' WHEN Umur BETWEEN 18 AND 59 THEN 'Dewasa' ELSE 'Lansia' END;

Klausa ORDER BY secara default hanya bisa mengurutkan berdasarkan nilai asli suatu kolom, baik secara alfabetis maupun numerik, padahal kebutuhan bisnis sering kali menuntut urutan kustom yang tidak mengikuti urutan alami tersebut, misalnya status 'Mendesak' harus selalu tampil lebih dulu meski secara alfabet huruf M berada di tengah. CASE WHEN pada ORDER BY mengatasi hal ini dengan memetakan setiap nilai ke angka prioritas tertentu, sehingga urutan akhir mengikuti angka tersebut, bukan nilai string aslinya.

Pada GROUP BY, CASE WHEN memungkinkan data dikelompokkan bukan berdasarkan nilai mentah suatu kolom, melainkan berdasarkan kategori atau rentang (bucket) yang didefinisikan sendiri, seperti mengelompokkan umur pelanggan ke dalam kategori Anak, Dewasa, dan Lansia. Teknik ini sangat umum dipakai dalam laporan ringkasan yang membutuhkan agregasi pada level kategori, bukan pada level nilai individual yang terlalu rinci.

Satu hal yang perlu diperhatikan adalah ekspresi CASE WHEN pada GROUP BY harus dituliskan persis sama dengan yang ada di SELECT, karena SQL Server memperlakukan keduanya sebagai ekspresi terpisah yang harus identik, bukan merujuk ke alias yang sama. Pada SQL Server versi yang mendukung, penggunaan subquery atau Common Table Expression untuk menghitung ekspresi CASE WHEN sekali saja lalu melakukan GROUP BY pada alias hasilnya dapat membuat query lebih ringkas dan menghindari duplikasi ekspresi yang panjang.

IIF Sebagai Bentuk Ringkas dari CASE WHEN Dua Kondisi

IIF sebagai shorthand CASE WHEN

-- CASE WHEN klasik untuk dua kemungkinan hasil SELECT NamaProduk, CASE WHEN Stok &gt; 0 THEN 'Tersedia' ELSE 'Habis' END AS StatusStok FROM dbo.Produk; -- IIF, bentuk ringkas untuk kondisi if-then-else sederhana SELECT NamaProduk, IIF(Stok &gt; 0, 'Tersedia', 'Habis') AS StatusStok FROM dbo.Produk; -- Hasil kedua query identik persis

IIF adalah fungsi bawaan SQL Server sejak versi 2012 yang menyederhanakan penulisan CASE WHEN untuk kasus dua kemungkinan hasil saja, dengan format IIF(kondisi, nilai_jika_benar, nilai_jika_salah). Secara internal, IIF sebenarnya diterjemahkan oleh SQL Server menjadi bentuk searched CASE WHEN yang setara, sehingga tidak ada perbedaan performa antara keduanya, murni perbedaan keringkasan penulisan.

IIF menjadi kurang praktis ketika kemungkinan hasil yang dibutuhkan lebih dari dua, karena IIF bersarang di dalam IIF lain membuat kode justru lebih sulit dibaca dibanding CASE WHEN dengan beberapa klausa WHEN sekaligus; pada situasi semacam itu, CASE WHEN klasik tetap menjadi pilihan yang lebih jelas dan lebih mudah dipelihara, sehingga IIF paling cocok dipakai khusus untuk kondisi biner sederhana.

Kesalahan Umum yang Sering Terjadi

Menulis kondisi CASE WHEN dalam urutan yang tidak logis

Karena evaluasi berhenti di kondisi pertama yang cocok, menulis kondisi umum sebelum kondisi spesifik bisa menyebabkan kondisi spesifik tersebut tidak pernah tercapai sama sekali.

Lupa menambahkan ELSE pada CASE WHEN

Tanpa ELSE, baris yang tidak memenuhi kondisi apa pun akan menghasilkan NULL, yang kadang tidak disadari dan menyebabkan data 'hilang' secara tidak terduga pada laporan.

Kapan Pendekatan Ini Tidak Cocok Dipakai

Conditional aggregation dengan CASE WHEN sangat praktis untuk laporan dengan jumlah kategori yang sudah pasti dan terbatas, namun untuk kategori yang jumlahnya dinamis (tidak diketahui di awal, misalnya berdasarkan data yang terus bertambah), pendekatan PIVOT dinamis atau pengolahan di sisi aplikasi akan lebih tepat dibanding menulis CASE WHEN manual untuk setiap kemungkinan nilai.

Ringkasan

CASE WHEN memberi fleksibilitas besar dalam menulis logika bisnis langsung di dalam query, mulai dari kategorisasi data, kontrol urutan sort, hingga laporan ringkas berbasis kondisi tertentu.

Menguasai pola conditional aggregation dengan CASE WHEN dan fungsi agregat adalah keterampilan yang sangat dihargai saat membuat laporan bisnis langsung dari database tanpa perlu tool BI tambahan.