Koşullu İfadeler: CASE WHEN, IF, NULLIF
Giriş — SQL'de Karar Verme
Programlama dillerinde if/else ile koşullu mantık kurarsın. SQL'de aynı işi CASE WHEN yapar. Bu, SELECT içinde "eğer şu koşul sağlanıyorsa şu değeri göster" demenin yoludur.
🎯 Analoji: Bir otomatik e-posta sistemi düşün: sipariş durumu "pending" ise "Siparişiniz alındı", "shipped" ise "Kargoya verildi", "delivered" ise "Teslim edildi" mesajı gönder. CASE WHEN tam olarak bu karar mekanizmasıdır.
CASE WHEN — SQL'in IF/ELSE'i
Basit CASE (Eşitlik Kontrolü)
CASE sütun
WHEN deger1 THEN sonuc1
WHEN deger2 THEN sonuc2
...
ELSE varsayılan_sonuc
END
-- Sipariş durumunu Türkçeleştir
SELECT order_id, status,
CASE status
WHEN 'pending' THEN 'Beklemede'
WHEN 'processing' THEN 'İşleniyor'
WHEN 'shipped' THEN 'Kargoda'
WHEN 'delivered' THEN 'Teslim Edildi'
WHEN 'cancelled' THEN 'İptal'
ELSE 'Bilinmiyor'
END AS durum_turkce
FROM orders;Searched CASE (Koşullu İfade)
Daha esnek — her WHEN'de farklı koşullar yazabilirsin:
CASE
WHEN koşul1 THEN sonuc1
WHEN koşul2 THEN sonuc2
...
ELSE varsayılan_sonuc
END
-- Fiyat kategorileri
SELECT product_name, price,
CASE
WHEN price < 100 THEN 'Ekonomik'
WHEN price < 1000 THEN 'Uygun'
WHEN price < 10000 THEN 'Orta Segment'
WHEN price < 50000 THEN 'Premium'
ELSE 'Lüks'
END AS fiyat_segmenti
FROM products;⚠️ Dikkat: CASE WHEN koşulları sırayla değerlendirilir. İlk TRUE olan koşulun sonucu döner ve geri kalanı kontrol edilmez. Bu yüzden koşul sırası önemlidir:
-- ❌ YANLIŞ sıra — her şey "Ucuz" olur
CASE
WHEN price > 0 THEN 'Ucuz' -- Her pozitif fiyat buraya düşer!
WHEN price > 1000 THEN 'Orta' -- Asla çalışmaz
WHEN price > 10000 THEN 'Pahalı' -- Asla çalışmaz
END
-- ✅ DOĞRU sıra — dar koşuldan geniş koşula
CASE
WHEN price > 10000 THEN 'Pahalı'
WHEN price > 1000 THEN 'Orta'
WHEN price > 0 THEN 'Ucuz'
ENDCASE WHEN ile NULL Kontrolü
SELECT product_name,
CASE
WHEN stock_quantity IS NULL THEN 'Bilgi Yok'
WHEN stock_quantity = 0 THEN 'Tükendi'
WHEN stock_quantity < 10 THEN 'Son Birkaç Adet!'
WHEN stock_quantity < 50 THEN 'Sınırlı Stok'
ELSE 'Stokta'
END AS stok_durumu
FROM products;WHERE'de CASE
-- Koşullu filtreleme
SELECT * FROM orders
WHERE status = CASE
WHEN DAYOFWEEK(NOW()) IN (1, 7) THEN 'pending' -- Hafta sonu: bekleyenler
ELSE 'processing' -- Hafta içi: işlenenler
END;ORDER BY'da CASE
-- Özel sıralama: önce kritik stoklar
SELECT product_name, stock_quantity FROM products
ORDER BY
CASE
WHEN stock_quantity = 0 THEN 1 -- En üste
WHEN stock_quantity < 10 THEN 2 -- İkinci
WHEN stock_quantity < 50 THEN 3 -- Üçüncü
ELSE 4 -- En alta
END ASC,
stock_quantity ASC;UPDATE'te CASE
-- Toplu fiyat güncelleme: kategoriye göre farklı zam
UPDATE products
SET price = CASE
WHEN category_id IN (1, 2, 3) THEN ROUND(price * 1.10, 2) -- Elektronik: %10
WHEN category_id IN (4, 5, 6) THEN ROUND(price * 1.05, 2) -- Giyim: %5
WHEN category_id = 7 THEN ROUND(price * 1.03, 2) -- Kitap: %3
ELSE price -- Değiştirme
END
WHERE is_active = TRUE;IF() Fonksiyonu — İki Seçenekli Kısa Yol
MySQL'e özel basit if/else:
IF(koşul, doğruysa_değer, yanlışsa_değer)
-- Boolean sütunu okunabilir hale getir
SELECT product_name,
IF(is_active, 'Aktif', 'Pasif') AS durum
FROM products;
-- Stok kontrolü
SELECT product_name,
IF(stock_quantity > 0, 'Stokta', 'Tükendi') AS stok
FROM products;
-- NULL kontrolü
SELECT first_name,
IF(phone IS NOT NULL, phone, 'Belirtilmemiş') AS telefon
FROM customers;CASE vs IF karşılaştırması:
-- IF: Sadece 2 seçenek (ternary operatör gibi)
SELECT IF(price > 1000, 'Pahalı', 'Uygun') FROM products;
-- CASE: Çoklu seçenek (if/elif/else gibi)
SELECT CASE
WHEN price > 10000 THEN 'Çok Pahalı'
WHEN price > 1000 THEN 'Pahalı'
ELSE 'Uygun'
END FROM products;💡 İpucu: 2 seçenek varsa
IF(), 3+ seçenek varsaCASE WHENkullan.CASE WHENSQL standardıdır ve her yerde çalışır;IF()MySQL'e özeldir.
NULLIF — Eşitse NULL Yap
NULLIF'i daha önce gördük ama CASE WHEN bağlamında tekrar ele alalım:
-- NULLIF(a, b) → a = b ise NULL, değilse a
SELECT NULLIF(10, 10); -- NULL
SELECT NULLIF(10, 5); -- 10
-- Aslında CASE WHEN'in kısaltması:
-- NULLIF(a, b) = CASE WHEN a = b THEN NULL ELSE a END
-- Sıfıra bölme koruması (en yaygın kullanım)
SELECT order_id,
total_amount,
item_count,
ROUND(total_amount / NULLIF(item_count, 0), 2) AS avg_item_price
FROM (
SELECT o.order_id, o.total_amount, COUNT(oi.item_id) AS item_count
FROM orders o
LEFT JOIN order_items oi ON o.order_id = oi.order_id
GROUP BY o.order_id, o.total_amount
) AS order_summary;Gerçek Dünya Örneği — E-Ticaret Dashboard
-- Sipariş dashboard'u — her sipariş için detaylı durum bilgisi
SELECT
o.order_id,
CONCAT(c.first_name, ' ', c.last_name) AS musteri,
DATE_FORMAT(o.order_date, '%d.%m.%Y') AS tarih,
CONCAT('₺', FORMAT(o.total_amount, 2)) AS tutar,
-- Durum badge'i
CASE o.status
WHEN 'pending' THEN '🟡 Beklemede'
WHEN 'processing' THEN '🔵 İşleniyor'
WHEN 'shipped' THEN '🟣 Kargoda'
WHEN 'delivered' THEN '🟢 Teslim'
WHEN 'cancelled' THEN '🔴 İptal'
END AS durum,
-- Aciliyet
CASE
WHEN o.status = 'pending' AND DATEDIFF(NOW(), o.order_date) > 3
THEN '⚠️ ACİL'
WHEN o.status = 'pending' AND DATEDIFF(NOW(), o.order_date) > 1
THEN '⏳ Takipte'
WHEN o.status IN ('delivered', 'cancelled')
THEN '✅ Kapandı'
ELSE '📋 Normal'
END AS aciliyet,
-- Geçen süre
CONCAT(DATEDIFF(NOW(), o.order_date), ' gün') AS gecen_sure
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
ORDER BY
CASE o.status
WHEN 'pending' THEN 1
WHEN 'processing' THEN 2
WHEN 'shipped' THEN 3
WHEN 'delivered' THEN 4
WHEN 'cancelled' THEN 5
END,
o.order_date ASC;Sıkça Yapılan Hatalar
CASE WHEN koşul sırası: Geniş koşuldan dar koşula gidersen ilk koşul her şeyi yakalar. Dar→geniş sıra kullan.
ELSE unutmak: ELSE olmadan hiçbir koşula uymayan satırlar NULL döner. Genellikle ELSE yazmak iyi pratiktir.
END unutmak: Her CASE bir END ile kapatılmalıdır. Unutursan syntax hatası alırsın.
IF() ile CASE karıştırmak: IF() iki seçenekli, CASE çoklu seçenekli. İkisini iç içe yazmak kodu okunamaz hale getirir.
SELECT dışında kullanmayı bilmemek: CASE WHEN sadece SELECT'te değil, WHERE, ORDER BY, UPDATE SET, INSERT VALUES, HAVING — neredeyse her yerde kullanılabilir.
Özet
CASE WHEN SQL'in if/else mekanizmasıdır — çoklu koşullu mantık kurar
Basit CASE (
CASE sütun WHEN değer) eşitlik kontrolü, Searched CASE (CASE WHEN koşul) esnek karşılaştırma yaparCASE koşulları sırayla değerlendirilir — dar koşuldan geniş koşula yaz
IF() MySQL'e özel, 2 seçenekli kısa yol. 3+ seçenekte CASE kullan
NULLIF iki değer eşitse NULL döndürür — sıfıra bölme koruması
CASE WHEN SELECT, WHERE, ORDER BY, UPDATE, INSERT — her yerde çalışır
ELSE yazmayı unutma — yoksa uyumsuz satırlar NULL döner
AI Asistan
Sorularını yanıtlamaya hazır