- Aramalı ve basit
CASEifadeleriniSELECTveORDER BYiçinde kullanmak COALESCEileNULLdeğerleri değiştirmek veNULLIFile sıfıra bölmeden korunmak- Koşullu toplama ile satırları sütunlara çeviren bir pivot rapor kurmak
E-okul sistemi bir puanı gösterirken yanına harf notunu da yazar: 94 “A”, 81 “B”. Çevrim içi mağaza ürünün yanına “stokta yok” yazar, okul müdürü ise sınıflara ve şehirlere göre öğrenci sayısını tek bir tabloda görmek ister. Bunların hepsi sorgunun içindeki koşullardır ve SQL'de CASE ifadesiyle yazılır. CASE, diğer programlama dillerindeki if gibidir; ama bir komut değil, değer döndüren bir ifadedir. Bu yüzden bir sütunun yazılabildiği her yerde kullanılabilir.
Aramalı CASE: CASE WHEN ... THEN ... END
VTYS WHEN koşullarını yukarıdan aşağıya denetler ve ilk doğru koşulun THEN değerini döndürür; kalanlara artık bakmaz. Hiçbir koşul doğru değilse ELSE değeri, ELSE yazılmamışsa NULL döndürülür. İfade her zaman END ile biter ve genellikle AS ile bir ad verilir.
SELECT s.first_name, e.score,
CASE
WHEN e.score >= 90 THEN 'A'
WHEN e.score >= 80 THEN 'B'
WHEN e.score >= 70 THEN 'C'
ELSE 'D'
END AS letter
FROM enrollments AS e
JOIN students AS s ON s.id = e.student_id
WHERE e.course_id = 3
ORDER BY e.score DESC;▸ Beklenen çıktı
first_name | score | letter Fidan | 94 | A Murad | 81 | B Rəşad | 77 | C Elvin | 68 | D
Basit CASE ve CASE ile sıralama
Bir sütun birkaç belirli değerle karşılaştırılırken kısa bir biçim vardır: CASE sütun WHEN değer THEN ... END. Bu, = ile yapılan denetimlerin kısaltmasıdır. CASE, ORDER BY içinde de yazılabilir: aşağıda müşterileri para birimleriyle gösteriyor, Azerbaycan'daki müşterileri listenin başına alıyoruz.
SELECT name, country,
CASE country
WHEN 'Azerbaijan' THEN 'AZN'
WHEN 'Türkiye' THEN 'TRY'
WHEN 'Russia' THEN 'RUB'
WHEN 'United Kingdom' THEN 'GBP'
END AS currency
FROM customers
ORDER BY CASE WHEN country = 'Azerbaijan' THEN 0 ELSE 1 END, name;▸ Beklenen çıktı
name | country | currency Anar Mustafayev | Azerbaijan | AZN Lalə Əhmədova | Azerbaijan | AZN Zəhra Hüseynli | Azerbaijan | AZN Emre Yılmaz | Türkiye | TRY John Carter | United Kingdom | GBP Mehmet Kaya | Türkiye | TRY Olga Ivanova | Russia | RUB
COALESCE ve NULLIF
COALESCE(a, b, c) listedeki NULL olmayan ilk değeri döndürür; bu, CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ELSE c END ifadesinin kısa yazımıdır. NULLIF(a, b) ise tersini yapar: a = b olduğunda NULL, aksi hâlde a döndürür. Asıl görevi sıfıra bölmeyi zararsız hâle getirmektir: x / NULLIF(y, 0) ifadesinde y sıfırsa bölme NULL ile yapılır ve sonuç NULL olur.
SELECT p.name, p.stock,
COALESCE(SUM(o.quantity), 0) AS sold,
ROUND(1.0 * COALESCE(SUM(o.quantity), 0) / NULLIF(p.stock, 0), 3) AS sold_per_stock
FROM products AS p
LEFT JOIN orders AS o ON o.product_id = p.id
WHERE p.category = 'Electronics'
GROUP BY p.id, p.name, p.stock
ORDER BY p.id;▸ Beklenen çıktı
name | stock | sold | sold_per_stock Laptop | 8 | 1 | 0.125 Smartphone | 15 | 2 | 0.133 Headphones | 40 | 3 | 0.075 Monitor | 0 | 0 | NULL
NULL verir.Koşullu toplama ve pivot
CASE bir toplama fonksiyonunun içine yazıldığında çok güçlü bir araca dönüşür. SUM(CASE WHEN koşul THEN 1 ELSE 0 END) koşulu sağlayan satırları sayar. Böyle birkaç sütun yazarsak satırlardaki değerler sütunlara dönüşür; tıpkı Excel'deki pivot tablo gibi. Aşağıda her şehir için sınıflara göre öğrenci sayısını görüyoruz.
SELECT city,
SUM(CASE WHEN grade = 8 THEN 1 ELSE 0 END) AS g8,
SUM(CASE WHEN grade = 9 THEN 1 ELSE 0 END) AS g9,
SUM(CASE WHEN grade = 10 THEN 1 ELSE 0 END) AS g10,
SUM(CASE WHEN grade = 11 THEN 1 ELSE 0 END) AS g11,
COUNT(*) AS total
FROM students
GROUP BY city
ORDER BY total DESC, city;▸ Beklenen çıktı
city | g8 | g9 | g10 | g11 | total Bakı | 1 | 2 | 1 | 0 | 4 Gəncə | 0 | 0 | 1 | 1 | 2 Sumqayıt | 1 | 0 | 0 | 1 | 2 Lənkəran | 1 | 0 | 0 | 0 | 1 Naxçıvan | 0 | 0 | 0 | 1 | 1 Quba | 0 | 0 | 1 | 0 | 1 Şəki | 0 | 1 | 0 | 0 | 1
Aynı yöntemle paylar da hesaplanır: 0 ve 1'lerin ortalaması, koşulu sağlayan satırların payıdır. COUNT(CASE WHEN koşul THEN 1 END) de çalışır; çünkü ELSE yoksa değer NULL olur, COUNT ise NULL değerleri saymaz.
SELECT c.title,
COUNT(*) AS students,
COUNT(CASE WHEN e.score >= 90 THEN 1 END) AS excellent,
ROUND(100.0 * AVG(CASE WHEN e.score >= 90 THEN 1 ELSE 0 END), 1) AS excellent_pct
FROM enrollments AS e
JOIN courses AS c ON c.id = e.course_id
GROUP BY c.id, c.title
ORDER BY excellent_pct DESC, c.title;▸ Beklenen çıktı
title | students | excellent | excellent_pct Python Basics | 3 | 2 | 66.7 Algebra | 4 | 2 | 50 English B1 | 2 | 1 | 50 World History | 2 | 1 | 50 Geometry | 3 | 1 | 33.3 Mechanics | 4 | 1 | 25 Organic Chemistry | 2 | 0 | 0
| İşlem | SQLite | PostgreSQL | MySQL | SQL Server |
|---|---|---|---|---|
| Kısa if | IIF(c, a, b) | CASE | IF(c, a, b) | IIF(c, a, b) |
| Koşullu sayma | COUNT(*) FILTER (WHERE c) | COUNT(*) FILTER (WHERE c) | SUM(c) | SUM(CASE ...) |
| Hazır pivot | yok | crosstab (tablefunc eklentisi) | yok | PIVOT |
CASE ise her VTYS'de aynı çalışır; taşınabilir sorgular için onu seç. MySQL'de karşılaştırma 1 ya da 0 döndürdüğü için SUM(score >= 90) de sayar.Her ürün için adı, stoğu (stock) ve durumu (status) göster: stok 0 ise 'out of stock', 20'den azsa 'low', diğer durumlarda 'ok'. Sonucu stoğa, sonra ada göre sırala.
SELECT name, stock
-- add the status column with CASE
FROM products
ORDER BY stock, name;▸ Beklenen çıktı
name | stock | status Monitor | 0 | out of stock Laptop | 8 | low Smartphone | 15 | low Chess set | 18 | low Desk lamp | 25 | ok Headphones | 40 | ok Backpack | 60 | ok Water bottle | 120 | ok Pen set | 300 | ok Notebook | 500 | ok
Bir pivot rapor kur: her ülke (country) için sipariş edilen Electronics ürünlerinin toplam adedini (electronics) ve diğer kategorilerin toplam adedini (other) göster. Sonucu ülkeye göre sırala.
SELECT c.country
-- electronics and other
FROM orders AS o
JOIN customers AS c ON c.id = o.customer_id
JOIN products AS p ON p.id = o.product_id
GROUP BY c.country
ORDER BY c.country;▸ Beklenen çıktı
country | electronics | other Azerbaijan | 5 | 33 Russia | 0 | 1 Türkiye | 1 | 5 United Kingdom | 0 | 2
Önemli noktalar
CASE WHEN ... THEN ... ELSE ... ENDilk doğru koşulun değerini döndürür;ELSEyoksaNULLelde edilir.- Koşulları en darından en genişine doğru yaz;
CASE,SELECT,ORDER BY,WHEREiçinde ve toplama fonksiyonlarının içinde çalışır. COALESCENULLolmayan ilk değeri verir,NULLIF(y, 0)ise sıfıra bölmeden korur.SUM(CASE WHEN koşul THEN 1 ELSE 0 END)sayar,AVG(...)ise pay verir; pivot raporların temeli budur.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.
CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' WHEN score >= 70 THEN 'C' ELSE 'D' END ifadesi 85 puan için ne döndürür?