Program
Veritabanlarıyla çalıştıysanız, verilerin nadiren kusursuz olduğunu ve anlamlı içgörüler elde etmek için çoğunlukla dönüştürme gerektirdiğini muhtemelen fark etmişsinizdir.
Bu ihtiyacı karşılamak için SQL, mevcut sütunlara uygulanan koşullara göre yeni sütunlar oluşturmanıza veya verileri dönüştürmenize olanak tanıyan güçlü bir yapı sunar: CASE ifadesi.
Bu yazıda, CASE ifadesinin ne olduğunu, neden önemli olduğunu açıklayacak ve potansiyelinden yararlanmanıza yardımcı olacak çeşitli kullanım örneklerini inceleyeceğiz. Haydi başlayalım!
CASE ifadesi nedir?
SQL’de CASE ifadesi, sorgunuza karar verme mantığı kazandıran koşullu bir ifadedir. Python’daki if-elif-else ifadesine benzer şekilde çalışır; birden çok koşulu değerlendirmenize ve bu koşullara göre belirli sonuçlar döndürmenize olanak tanır.
Genel sözdizimi şöyledir:
CASE
WHEN boolean_condition1 THEN result1
WHEN boolean_condition2 THEN result2
ELSE result3
END
Nasıl çalıştığı şöyle:
- CASE anahtar sözcüğü ifadenin başlangıcını, END ise bitişini işaretler; koşullu ifadeyi bir çerçeve gibi içine alır.
- Her WHEN cümleciği bir koşulu değerlendirir. Koşul doğruysa, ilgili THEN cümleciği belirtilen sonucu döndürür.
- WHEN cümleciklerindeki koşulların hiçbiri sağlanmazsa, ELSE cümleciği varsayılan bir sonuç sağlar.
CASE ifadesi neden önemlidir?
CASE WHEN ifadesi, SQL sorgularında çeşitli temel faydalar sunan değerli bir araçtır:
- Veri dönüşümü: mevcut sütunların değerlerine dayalı olarak yeni sütunlar oluşturmanızı sağlar.
- Koşullu toplulaştırma: belirli koşullara göre veri alt kümeleri için (ör. toplam, sayım, maksimum) toplanmış değerler oluşturmanıza olanak tanır.
- Veri filtreleme: belirli ölçütlere göre satırları dahil edebilir veya hariç tutabilirsiniz.
- Sorgu basitleştirme ve okunabilirlik: Mantığı tek bir sorguda birleştirerek birden fazla sorguya, geçici tablolara veya karmaşık join’lere duyulan ihtiyacı azaltır.
- Performans optimizasyonu: SQL sorgularının karmaşıklığını azaltarak performansın optimize edilmesine ve yürütme süresinin kısalmasına katkıda bulunabilir; özellikle ek hesaplamalar ve dönüşümlerden kaçınıldığında.
Basit CASE ifadesi
Bu yazıda, cinema veritabanının film tablosunu kullanacağız. Diyelim ki ROI’ye (brüt/ bütçe oranı) göre yeni bir kategorik sütun oluşturmak istiyoruz:
SELECT
title,
gross,
budget,
gross / budget AS ROI,
CASE
WHEN gross / budget < 1 THEN 'low ROI'
WHEN gross / budget BETWEEN 1 AND 2 THEN 'medium ROI'
ELSE 'high ROI'
END as ROI_group
FROM cinema.films
WHERE budget > 0 AND gross > 0 AND release_year = 2015;

Brüt gelir ve bütçe verildiğinde, bir yatırımın ürettiği geliri ölçen ve yaygın bir kârlılık metriği olan ROI’yi hesapladık.
ROI alanına ek olarak, iletişimi kolaylaştırmak için bunu kategorilere de ayırdık:
- ROI’si 1’den küçük olan filmlerde değer “low ROI” olur.
- ROI’si 1 ile 2 arasında olan filmler “medium ROI” kategorisine girer.
- “High ROI” etiketi, ROI’si 2 veya daha yüksek olan filmlere atanır.
Ayrıca bütçesi veya brüt geliri sıfır ya da negatif olan filmleri dışarıda bıraktık. Bunun yanında, sonuçları 2015 yılında vizyona giren filmlerle sınırladık.
GROUP BY koşulunda CASE kullanma
İlk örnekte, verileri toplulaştırmak ve ek içgörüler elde etmek için uygulanabilecek yeni bir alan oluşturduk.
Örneğin, her ROI grubu için ortalama brüt gelir ve ortalama bütçeyi hesaplayabiliriz:
SELECT
CASE
WHEN gross / budget < 1 THEN 'low ROI'
WHEN gross / budget BETWEEN 1 AND 2 THEN 'medium ROI'
ELSE 'high ROI'
END AS ROI_group,
avg(gross) as avg_gross,
avg(budget) as avg_budget
FROM cinema.films
WHERE budget > 0 AND gross > 0 AND release_year = 2015
GROUP BY
CASE
WHEN gross / budget < 1 THEN 'low ROI'
WHEN gross / budget BETWEEN 1 AND 2 THEN 'medium ROI'
ELSE 'high ROI'
END
ORDER BY avg(gross) DESC
;

Verileri gruplamak için CASE ifadesini GROUP BY cümleciğine yerleştirdik. Ek içgörüler için satırları ortalama brüt gelire göre azalan düzende sıraladık. Böylece en yüksek ortalama brüt gelirin yüksek ROI grubuna, en düşüklerinin ise düşük ROI grubuna karşılık geldiğini görebiliriz.
WHERE koşulunda CASE kullanma
CASE ifadesinin bir diğer faydası, belirli koşullara göre satırları filtrelemeyi mümkün kılmasıdır. Örneğin, filmin diline bağlı olarak farklı ROI eşikleri uygulayabiliriz. İngilizce filmlerin genellikle yüksek ROI’ye sahip olduğu bilinir. Bu nedenle eşik daha yüksek olmalı; diğer diller için ise daha düşük bir ROI varsayabiliriz.
SELECT
title,
gross,
budget,
language,
gross / budget AS ROI
FROM cinema.films
WHERE
CASE
WHEN language = 'English' THEN gross / budget > 2 -- English films need ROI > 2
WHEN language = 'French' THEN gross / budget > 1.5 -- French films need ROI > 1.5
ELSE gross / budget > 1.3 -- Default for other languages
END;

Toplamaları (aggregations) hesaplama
2015’te vizyona giren, yüksek ROI’ye sahip filmler ile düşük ROI’ye sahip filmlerin sayısını da hesaplamak isteyebiliriz:
SELECT
SUM(CASE WHEN gross / budget > 2 THEN 1 ELSE 0 END) AS high_roi_films,
SUM(CASE WHEN gross / budget BETWEEN 1 AND 2 THEN 1 ELSE 0 END) AS medium_roi_films,
SUM(CASE WHEN gross / budget < 1 THEN 1 ELSE 0 END) AS low_roi_films
FROM cinema.films
WHERE budget > 0 AND gross > 0 AND release_year = 2015;

SUM işlevinin içinde, ROI bu eşiğe ulaştığında değeri 1 olan, aksi halde 0 olan yeni bir alan tanımlamış gibi oluruz. Bu yeni ikili değişkenin toplamını aldığımızda, ilgili ölçütü sağlayan film sayısını elde ederiz.
Çıktıdan, filmlerin çoğunun ROI’sinin 1’in altında olduğunu, çok az filmin ise yüksek derecede kârlı olduğunu görebiliriz.
İç içe (nested) CASE ifadesi
En gelişmiş kullanımlardan biri, bir CASE’in içinde başka bir CASE kullanılan iç içe CASE ifadesidir. Verileri alt gruplara ayırmanız ve her alt grup için farklı bir mantık uygulamanız gerektiğinde çok kullanışlıdır.
İlk örneğe benzer şekilde, ROI değerlerinden etkilenecek yeni bir sütun oluşturmak istiyoruz. Daha önce belirttiğimiz gibi, İngilizce filmler için ROI, diğer dillere kıyasla küresel ölçekte yüksektir.
Bu nedenle, filmleri hem ROI’yi hem de dili dikkate alarak ROI gruplarına ayırmak daha iyi olacaktır
SELECT
title,
language,
gross / budget AS ROI,
CASE
WHEN language = 'English' THEN
CASE
WHEN gross / budget < 2 THEN 'low ROI'
WHEN gross / budget BETWEEN 2 AND 3 THEN 'medium ROI'
ELSE 'high ROI'
END
ELSE
CASE
WHEN gross / budget < 1 THEN 'low ROI'
WHEN gross / budget BETWEEN 1 AND 2 THEN 'medium ROI'
ELSE 'high ROI'
END
END AS ROI_group
FROM cinema.films
WHERE budget > 0 AND gross > 0 and release_year = 2006;

Sorguda, dış CASE ifadesi dilin İngilizce olup olmadığını değerlendirir. Dile bağlı olarak, iç CASE ROI’yi değerlendirir: Eşikler İngilizce filmler için daha yüksek, İngilizce olmayanlar için daha düşüktür. Bu çok seviyeli koşullandırma, düşük, orta ve yüksek ROI’li filmlerin ayrımını iyileştirmeye olanak tanır.
Sonuç
CASE ifadesi, verilerinizden anlamlı içgörüler çıkarmak için vazgeçilmez bir SQL yapısıdır. Bu güçlü koşullu ifadeyi derinlemesine kavramanıza yardımcı olmak için teori ile pratik örnekleri bir araya getirdik. Daha derine inmek isterseniz SQL’de veri işleme kursuna göz atın. CASE ifadesinin yanı sıra alt sorgular ve pencere fonksiyonları gibi diğer temel SQL konularını da kapsar. Son olarak, SQL’i ustalıkla öğrenmenize yardımcı olacak kurslara genel bir bakış için SQL Fundamentals bölümüne göz atabilirsiniz.
