SQL COALESCE, NULL olabilecek bir alanı alternatif bir değerle göstermek veya hesaplamalarda kullanılabilir hâle getirmek için kullanılır. Ancak COALESCE yalnızca NULL değerleri ele alır; boş string ve sayısal 0, NULL ile aynı anlama gelmez. Bu nedenle doğru sonuç için önce verinin iş anlamını belirlemelisin.
COALESCE Nedir ve İlk NULL Olmayan Değeri Nasıl Seçer?
COALESCE, kendisine verilen ifadeleri soldan sağa kontrol eder ve ilk NULL olmayan değeri döndürür. Bütün ifadeler NULL ise sorgunun sonucu da NULL olur. Genel söz dizimi şöyledir:
COALESCE(deger1, deger2, deger3)
En temel kullanım, NULL olan bir sütunun yerine tek bir yedek değer göstermektir:
SELECT COALESCE(musteri_telefonu, 'Telefon yok') AS telefon
FROM siparisler;
musteri_telefonu alanında 0555 111 22 33 varsa sonuç bu numaradır. Alan NULL ise beklenen çıktı Telefon yok olur. Bu işlem tablodaki asıl veriyi değiştirmez; yalnızca sorgu sonucunun nasıl gösterileceğini belirler.
COALESCE birden fazla alternatifi de sırayla deneyebilir. Örneğin sipariş için önce müşterinin adı, ardından alternatif telefonu, son olarak varsayılan bir metin kullanılabilir:
SELECT
siparis_id,
COALESCE(musteri_adi, alternatif_telefon, 'İletişim bilgisi yok')
AS iletisim
FROM siparisler;
Örnek bir satırda musteri_adi = 'Ayşe Yılmaz' ve alternatif_telefon = '0532 444 55 66' ise beklenen çıktı Ayşe Yılmaz olur. İlk ifade zaten NULL olmadığı için sağdaki alternatif telefon sonuç olarak seçilmez. Müşteri adı NULL, alternatif telefon doluysa telefon numarası; ikisi de NULL ise İletişim bilgisi yok döner.
PostgreSQL’in resmî dokümantasyonunda COALESCE’nin yalnızca sonucu belirlemek için gereken ifadeleri değerlendirdiği, ilk NULL olmayan ifadenin sağındaki seçeneklerin çalıştırılmadığı belirtilir. Bununla birlikte ifadelerin uyumlu bir ortak veri türüne dönüştürülebilmesi gerekir. Bu nedenle metin, sayı ve tarih gibi farklı türleri bilinçsizce aynı COALESCE içinde birleştirmemelisin.
NULL, Boş String ve 0 Aynı Şey Değildir: Sipariş Senaryosu

siparisler tablosunda şu alanların bulunduğunu düşünelim: siparis_id, indirim, teslimat_notu ve musteri_telefonu. Üç örnek satır farklı iş durumlarını temsil etsin:
siparis_id | indirim | teslimat_notu | musteri_telefonu
-----------+---------+----------------+------------------
101 | NULL | NULL | NULL
102 | 0 | '' | 0555 111 22 33
103 | 15 | Kapıyı çalın | 0532 444 55 66
İlk satırdaki NULL indirim, indirim bilgisinin girilmediğini veya bilinmediğini anlatabilir. İkinci satırdaki 0 ise bilginin mevcut olduğunu ve siparişe gerçekten indirim uygulanmadığını ifade eder. Benzer biçimde NULL teslimat notu ile '' boş string aynı veri değildir: biri değerin bulunmadığını, diğeri metin alanına sıfır karakterli bir değer kaydedildiğini gösterebilir.
İndirim raporunda eksik değeri 0 göstermek için şu sorgu kullanılabilir:
SELECT siparis_id, COALESCE(indirim, 0) AS gosterilen_indirim
FROM siparisler;
Beklenen çıktılar sırasıyla 0, 0 ve 15 olur. Burada 101 ve 102 aynı görünse de kaynak verilerinin anlamı farklıdır. Bu nedenle COALESCE, raporu kolaylaştırırken “bilinmeyen indirim” ile “indirimsiz sipariş” ayrımını görünmez hâle getirebilir.
Teslimat notu için şu sorguyu ele alalım:
SELECT siparis_id,
COALESCE(teslimat_notu, 'Not girilmedi') AS not_metni
FROM siparisler;
101 numaralı siparişte beklenen çıktı Not girilmedi, 102 numaralı siparişte ise boş bir metindir. Çünkü boş string’in NULL’dan ayrı tutulduğu sistemlerde COALESCE, '' değerini geçerli ilk değer olarak kabul eder. 103 numaralı siparişte sonuç Kapıyı çalın olur.
Telefon sorgusunda da aynı mantık geçerlidir:
SELECT siparis_id,
COALESCE(musteri_telefonu, 'Telefon yok') AS telefon
FROM siparisler;
Beklenen sonuç 101 için Telefon yok, diğer iki sipariş için kayıtlı telefon numarasıdır.
Boş string davranışı veritabanı motoruna göre değişebildiğinden taşınabilir sorgularda dikkatli olmalısın. Örneğin PostgreSQL boş string’i metinsel bir değer olarak işleyebilirken Oracle belgelerinde sıfır uzunluklu karakter değerinin NULL olarak ele alındığı açıklanır. Boş veya yalnızca boşluklardan oluşan notları da eksik kabul etmek istiyorsan PostgreSQL gibi uygun motorlarda açık bir normalleştirme yazabilirsin:
COALESCE(NULLIF(TRIM(teslimat_notu), ''), 'Not girilmedi')
TRIM kenar boşluklarını kaldırır, NULLIF kalan değer boşsa onu NULL’a çevirir ve COALESCE varsayılan metni döndürür. Böylece eksik veri kuralı tesadüfi motor davranışına değil, açıkça tanımladığın iş mantığına dayanır.
Raporlarda Varsayılan Değer Seçimi Sonucu Nasıl Değiştirir?

COALESCE, rapor sorgularında eksik bir değeri hesaplamaya dâhil etmek için kullanılabilir; ancak seçtiğin varsayılan değer, raporun anlamını doğrudan değiştirir. Bu nedenle önce iş kuralını netleştirmelisin: indirim alanındaki NULL, gerçekten “indirim uygulanmadı” mı demek, yoksa bu bilgi henüz girilmedi mi?
Örneğin sipariş tablosunda toplam_tutar ve indirim alanları bulunduğunu düşünelim:
SELECT
siparis_id,
toplam_tutar,
indirim,
toplam_tutar - indirim AS odenecek_tutar
FROM siparisler;
indirim değeri NULL olan bir kayıtta, matematiksel işlem sonucu çoğu SQL motorunda NULL olur. Yani toplam tutar 500, indirim NULL ise sorgu 500 yerine NULL döndürebilir. Bu, “ödenecek tutar bilinmiyor” anlamına gelir; “indirim yok” anlamına gelmez.
Eğer sistemde NULL indirim açıkça “indirim uygulanmadı” anlamında kullanılıyorsa şu sorgu daha uygun olabilir:
SELECT
siparis_id,
toplam_tutar,
COALESCE(indirim, 0) AS uygulanan_indirim,
toplam_tutar - COALESCE(indirim, 0) AS odenecek_tutar
FROM siparisler;
Örneğin toplam_tutar = 500 ve indirim = NULL olan siparişte beklenen sonuç, uygulanan_indirim = 0 ve odenecek_tutar = 500 olur. Buna karşılık indirim = 0 olan bir kayıtta değer zaten sıfırdır; burada sistem indirim bilgisini bilmekte ve indirim uygulanmadığını açıkça göstermektedir. NULL ise veri yokluğunu, 0 ise gerçek bir sayısal değeri temsil edebilir.
Bu ayrım toplu raporlarda daha da önemlidir. Örneğin dört siparişte indirim değerleri NULL, 0, 20 ve 40 olsun. NULL değerleri 0 kabul edersen toplam indirim 60 olur. Fakat NULL “bilgi girilmedi” anlamındaysa, raporun gerçek toplamı “en az 60” olabilir; eksik kayıtlar ayrıca incelenmelidir. Ortalama da değişir: NULL değerleri dışarıda bırakan bir ortalama ile NULL değerleri 0’a çeviren ortalama aynı sonucu vermez. İndirim oranı hesabında da aynı sorun görülür:
SELECT
AVG(indirim) AS ortalama_indirim,
SUM(indirim) / NULLIF(SUM(toplam_tutar), 0) AS indirim_orani
FROM siparisler;
Burada AVG(indirim), kullanılan motora ve ifadeye göre NULL kayıtları hesaplamaya dâhil etmeyebilir. AVG(COALESCE(indirim, 0)) ise eksik indirimleri sıfır kabul eder. İlk sorgu yalnızca bilinen indirimlerin ortalamasını, ikinci sorgu ise tüm siparişlerde indirim yokmuş gibi hesaplanan ortalamayı temsil eder. Bu yüzden raporda “veri yok” ile “değer sıfır” ayrımını kaybetmemelisin.
COALESCE argümanlarında farklı veri türlerini bir araya getirirken de dikkatli olmalısın. Sayısal bir alanı metinle veya farklı hassasiyetteki sayısal türlerle birleştirmek örtük dönüşüm, yuvarlama ya da hata üretebilir. SQL Server gibi motorlarda COALESCE sonucunun veri türü belirlenirken tür önceliği kuralları dikkate alınır; desteklenmeyen örtük dönüşümlerde hata oluşabilir. Bu nedenle özellikle para, oran ve tarih hesaplarında açık CAST kullanmayı düşünmelisin. Ayrıntılar veritabanı motoruna göre değişebileceğinden sorguyu kullandığın motor üzerinde test etmelisin.
Bu tür sorguları adım adım kurarken önce temel SQL hesaplarını, ardından NULL yönetimini ve rapor doğrulamasını öğrenmek yararlıdır. Konuyu uygulamalı biçimde ilerletmek istersen video yazılım eğitimleri içindeki örnek odaklı çalışma düzeninden yararlanabilirsin.
Sıralama ve Gösterim İçin COALESCE Kullanırken Nelere Dikkat Edilmeli?
COALESCE yalnızca ekranda görünen değeri değil, ORDER BY içinde kullandığın sıralama değerini de değiştirebilir. Örneğin teslimat notlarını boş bırakılan kayıtlarda açıklayıcı göstermek için şu ifade kullanılabilir:
SELECT
siparis_id,
COALESCE(teslimat_notu, 'Not girilmedi') AS teslimat_notu
FROM siparisler;
Bu kullanım yalnızca gösterim amaçlıysa genellikle anlaşılırdır. Fakat aynı ifadeyi sıralamada kullanırsan:
ORDER BY COALESCE(teslimat_notu, 'Not girilmedi');
NULL kayıtları artık kendi NULL durumlarına göre değil, 'Not girilmedi' metnine göre sıralanır. Bu sonuç kullanıcı için mantıklı olmayabilir; çünkü rapor, not girilmiş siparişlerle notu eksik siparişleri alfabetik bir metin düzenine sokabilir.
NULL kayıtlarını ayrı bir grup hâlinde göstermek istiyorsan sıralama ölçütünü açıkça tanımlayabilirsin:
ORDER BY
CASE WHEN teslimat_notu IS NULL THEN 1 ELSE 0 END,
teslimat_notu;
Bu yaklaşımda önce notu bulunan kayıtlar, ardından notu bulunmayan kayıtlar gelir. Benzer karar müşteri telefonu için de geçerlidir: COALESCE(telefon, 'Telefon yok') ekranda okunabilir bir metin sağlayabilir; fakat telefon numarasını sıralamak veya filtrelemek için kullanılan alanın yerine geçmemelidir.
Rapor tasarımında kendine şu üç soruyu sor:
- Varsayılan değer yalnızca görüntüleme için mi kullanılacak?
- Bir hesaplamanın parçası olarak mı kullanılacak?
- Filtreleme veya sıralama sonucunu da değiştirmesi isteniyor mu?
Bu soruların cevabı farklıysa gösterim ve hesaplama ifadelerini birbirinden ayır. Ayrıca NULL değerlerin ASC veya DESC sıralamasındaki varsayılan konumu veritabanı motoruna göre değişebilir. Bazı motorlar NULLS FIRST ve NULLS LAST seçeneklerini destekler; PostgreSQL’de bu seçeneklerle konum açıkça belirtilebilir.
COALESCE mi CASE WHEN mi? Güvenli Kullanım Kontrol Listesi
Seçim yaparken sorgunun amacına bak: Yalnızca ilk kullanılabilir değeri seçmek veya NULL yerine basit bir yedek göstermek istiyorsan COALESCE daha kısa ve okunabilir bir çözümdür. Koşula, karşılaştırmaya ya da birden fazla iş kuralına göre farklı sonuçlar üretmen gerekiyorsa CASE WHEN kullanmalısın.
SELECT
siparis_id,
COALESCE(teslimat_notu, 'Not belirtilmedi') AS not_gorunumu
FROM siparisler;
Bu sorgu, teslimat notu NULL olan siparişlerde “Not belirtilmedi” metnini gösterir. Ancak yalnızca NULL kontrolü yapar; notun boş string olması veya belirli bir ifadeyi içermesi gibi koşulları değerlendirmez.
SELECT
siparis_id,
CASE
WHEN indirim_orani IS NULL THEN 'İndirim bilgisi yok'
WHEN indirim_orani = 0 THEN 'İndirim uygulanmadı'
ELSE 'İndirim uygulandı'
END AS indirim_durumu
FROM siparisler;
Burada NULL, 0 ve pozitif indirim oranları farklı iş anlamlarına sahiptir. Beklenen çıktı, her siparişin bu üç durumdan uygun olanıyla etiketlenmesidir. Aynı ayrımı yalnızca COALESCE(indirim_orani, 0) ile yaparsan “bilinmiyor” ile “indirim yok” durumlarını birbirine karıştırırsın.
COALESCE kullanmadan önce sorunu adım adım teşhis et
- NULL değerinin “bilinmiyor”, “girilmedi” veya “uygulanamaz” anlamlarından hangisini taşıdığını belirle.
- NULL yerine 0 yazmanın hesaplama ve filtreleme sonuçlarını değiştirip değiştirmediğini kontrol et.
- Boş string değerini otomatik olarak NULL kabul etme;
''ile NULL aynı durum değildir. - Müşteri telefonu gibi metin alanlarını sayısal yedeklerle gelişigüzel birleştirme. COALESCE içindeki değerlerin uyumlu veri türlerinde olmasına dikkat et.
- Gösterim amacıyla yapılan dönüşümü asıl hesaplama alanından ayır. Ekranda güzel görünmesi için eklenen bir varsayılan değer, veri analizinin anlamını değiştirmemelidir.
- COALESCE kullanılan ifadenin raporun
WHERE, sıralama veya gruplama mantığını etkileyip etkilemediğini örnek kayıtlarla sınayarak doğrula.
Bu kararları daha rahat verebilmek için yalnızca SQL sözdizimini değil, koşulları ve veri durumlarını adımlara ayırmayı da öğrenmek gerekir. SQL öncesinde bu becerini değerlendirmek istersen algoritmik düşünme testleri üzerinden farklı problem türlerini inceleyebilirsin.
Mini kontrol listesi
- NULL değerinin iş anlamı belirlendi mi?
- Seçilen varsayılan değer verinin anlamını bozuyor mu?
- COALESCE içindeki veri türleri birbiriyle uyumlu mu?
- Hesaplama ile kullanıcıya gösterilecek çıktı ayrıldı mı?
- Sorgunun beklenen çıktısı örnek kayıtlarla kontrol edildi mi?
Sık Sorulan Sorular
COALESCE ile ISNULL veya benzeri işlevler arasındaki fark nedir?
COALESCE, birden fazla ifade arasından ilk NULL olmayan değeri seçmek için kullanılır. ISNULL ve benzeri işlevlerin desteklenmesi, parametre sayısı, veri türü belirleme kuralları ve davranış ayrıntıları veri tabanı sistemine göre değişebilir. Bu nedenle taşınabilir sorgularda COALESCE tercih edilebilir; motor özelindeki davranışlar için kullanılan veri tabanının belgeleri kontrol edilmelidir.
COALESCE boş string değerlerini otomatik olarak NULL kabul eder mi?
Hayır. Boş string '' ile NULL aynı kavram değildir. Hem NULL hem de boş string için yedek değer göstermek istiyorsan boş string durumunu ayrıca kontrol etmelisin.
COALESCE kullanarak NULL değeri 0 yapmak her zaman doğru mudur?
Hayır. 0 gerçek bir sayısal değerdir; NULL ise değerin bilinmediğini veya bulunmadığını anlatabilir. İkisini birleştirmek toplam, ortalama, filtreleme ve raporlama sonuçlarının anlamını değiştirebilir.
COALESCE yerine CASE WHEN kullanmam gereken durumlar nelerdir?
Sonuç yalnızca NULL olup olmamasına değil; değerin 0 olması, belirli bir aralıkta bulunması, başka bir sütunla karşılaştırılması veya birden fazla iş kuralının birlikte değerlendirilmesine bağlıysa CASE WHEN daha uygundur.
COALESCE güvenli kullanıldığında sorguları sadeleştirir; doğru sonuç içinse önce NULL’ın anlamını belirlemek, ardından hesaplama ile gösterim ihtiyaçlarını birbirinden ayırmak gerekir.