Bir sütundaki eksik değeri bulmak için IS NULL, dolu değerleri bulmak için IS NOT NULL kullanılır. Eşittir işaretiyle yapılan karşılaştırma NULL üzerinde sonuç vermez. Sorgu hata göstermeden çalışır ama beklediğin satırları getirmez. Aşağıda tek bir müşteri tablosu üzerinden çalışan sorgular ve beklenen çıktılar var.
NULL kontrolü: IS NULL ve IS NOT NULL ile
SQL'de NULL aramak için = NULL yazılmaz; doğru sözdizimi IS NULL ifadesidir.
NULL, "0" ya da "boş yazı" gibi belirli bir değer değildir. "Bu bilgi bilinmiyor ya da kayıtta yok" durumunun adıdır. Bu yüzden iki NULL'ı birbirine eşit saymak mümkün değildir. Bilinmeyen bir şeyin başka bir bilinmeyene eşit olup olmadığı da bilinmez.
Bu yazının tamamında aynı musteriler tablosunu kullanacağız:
CREATE TABLE musteriler (
id INTEGER,
ad VARCHAR(50),
eposta VARCHAR(100),
siparis_sayisi INTEGER
);
INSERT INTO musteriler VALUES (1, 'Ayşe', '[email protected]', 4);
INSERT INTO musteriler VALUES (2, 'Burak', NULL, 2);
INSERT INTO musteriler VALUES (3, 'Cem', '', 1);
INSERT INTO musteriler VALUES (4, 'Deniz', '[email protected]', 0);
INSERT INTO musteriler VALUES (5, 'Elif', '[email protected]', NULL);
Tabloda şunlar var: Burak'ın e-postası NULL, Cem'in e-postası boş metin (''), Deniz'in sipariş sayısı 0, Elif'in sipariş sayısı NULL. Ayşe'nin kaydı tam dolu.
İletişim bilgisi eksik müşterileri bulmak için:
SELECT id, ad
FROM musteriler
WHERE eposta IS NULL;
id | ad
---+-------
2 | Burak
E-postası NULL olmayan kayıtları listelemek için:
SELECT id, ad, eposta
FROM musteriler
WHERE eposta IS NOT NULL;
id | ad | eposta
---+-------+-----------------
1 | Ayşe | [email protected]
3 | Cem |
4 | Deniz | [email protected]
5 | Elif | [email protected]
Cem'in satırına dikkat et: e-posta alanı boş görünüyor ama NULL olmadığı için IS NOT NULL sonucunda yer alıyor. Boş metin ile NULL arasındaki farka ilerleyen bölümde döneceğiz.
= NULL yazınca neden satır dönmüyor?

Aynı kontrolü eşittir işaretiyle yazmayı dene:
SELECT id, ad
FROM musteriler
WHERE eposta = NULL;
SELECT id, ad
FROM musteriler
WHERE eposta <> NULL;
Sonuç: 0 satır
Sonuç: 0 satır
İki sorgu da hatasız çalışır ve ikisi de boş döner. Burak'ı = ile bulamazsın, Burak dışındakileri de <> ile getiremezsin. "Sorgu çalıştı ama sonuç yanlış" durumunu şu üç adımla teşhis edebilirsin:
- Karşılaştırmanın sonucu TRUE olmaz, UNKNOWN olur. Bir değeri NULL ile karşılaştırdığında SQL "eşit mi?" sorusuna "bilmiyorum" der.
- WHERE yalnızca TRUE olan satırları alır. Sonucu FALSE ya da UNKNOWN olan satırlar elenir.
- NULL = NULL de UNKNOWN'dur. İki bilinmeyen değerin eşit olup olmadığı bilinmediği için bu karşılaştırma da satır getirmez.
SQL bu yüzden iki değil, üç değerli mantıkla çalışır: TRUE, FALSE ve UNKNOWN. NULL içeren her karşılaştırma UNKNOWN üretir. Bu yüzden NULL'ı sorgulamak için karşılaştırma işleci değil, ona özel yazılmış IS NULL ve IS NOT NULL kullanılır.
Aynı tuzak <> ile NULL içermeyen bir değer karşılaştırırken de karşına çıkar:
SELECT ad, siparis_sayisi
FROM musteriler
WHERE siparis_sayisi <> 0;
ad | siparis_sayisi
------+---------------
Ayşe | 4
Burak | 2
Cem | 1
Elif'in sipariş sayısı NULL olduğu için NULL <> 0 UNKNOWN çıkar ve satır sonuçta görünmez. "Sıfır olmayanlar" derken Elif'i de istiyorsan koşulu WHERE siparis_sayisi <> 0 OR siparis_sayisi IS NULL biçiminde yazman gerekir.
NULL, boş metin ve sıfır: üç farklı durum

Üçü de "boş" gibi görünür ama SQL'de farklı şeyleri anlatır. Hangi sorguyu yazacağını, değerin ne anlama geldiğine bakarak seçersin.
| Durum | Anlamı | Örnek değer | Yakalayan sorgu |
|---|---|---|---|
| NULL | Bilgi yok ya da bilinmiyor | NULL | IS NULL |
| Boş metin | E-posta alanı bilinçli olarak boş girildi | '' | = '' |
| Sıfır | Bilinen bir sayı: sipariş yok | 0 | = 0 |
Örnek musteriler tablosu 5 satırdan oluşuyor:
id | ad | eposta | siparis_sayisi
1 | Ayşe | [email protected] | 3
2 | Burak | NULL | 0
3 | Ceren | '' | NULL
4 | Deniz | [email protected] | NULL
5 | Emre | NULL | 5
Aşağıdaki sorgu her satırın durumunu yan yana gösterir:
SELECT id, ad,
CASE WHEN eposta IS NULL THEN 'NULL'
WHEN eposta = '' THEN 'boş metin'
ELSE 'dolu' END AS eposta_durumu,
CASE WHEN siparis_sayisi IS NULL THEN 'NULL'
WHEN siparis_sayisi = 0 THEN 'sıfır'
ELSE 'dolu' END AS siparis_durumu
FROM musteriler;
Beklenen çıktı:
id | ad | eposta_durumu | siparis_durumu
1 | Ayşe | dolu | dolu
2 | Burak | NULL | sıfır
3 | Ceren | boş metin | NULL
4 | Deniz | dolu | NULL
5 | Emre | NULL | dolu
Burak'ın sipariş sayısı 0'dır, yani "sipariş vermedi" bilgisi bellidir. Ceren ve Deniz'in sipariş sayısı ise NULL'dır, yani bilinmiyor. Bu yüzden siparis_sayisi = 0 yalnız Burak'ı (id 2), siparis_sayisi IS NULL ise Ceren ve Deniz'i (id 3 ve 4) döndürür. Sıfır, NULL değildir ve biri diğerinin yerine kullanılamaz.
İletişim bilgisi gerçekten eksik müşterileri bulmak için NULL ile boş metni birlikte aramak gerekir:
SELECT id, ad
FROM musteriler
WHERE eposta IS NULL OR eposta = '';
id | ad
2 | Burak
3 | Ceren
5 | Emre
Yalnız IS NULL yazsaydın Ceren listede görünmezdi, çünkü boş metin NULL değildir; bilinçli girilmiş, içi boş bir metindir.
COUNT(*) ile COUNT(sütun) farkı
COUNT(*) tüm satırları sayar. COUNT(sütun) ise yalnız o sütunda NULL olmayan satırları sayar. Aynı tabloda ikisini yan yana çalıştır:
SELECT COUNT(*), COUNT(eposta), COUNT(siparis_sayisi)
FROM musteriler;
COUNT(*) | COUNT(eposta) | COUNT(siparis_sayisi)
5 | 3 | 3
COUNT(eposta) 3 döner, çünkü Ayşe, Ceren ve Deniz'in e-posta değeri NULL değildir. Ceren'in boş metni de bu üçün içindedir. Sayım NULL'a bakar, metnin içi dolu mu boş mu diye bakmaz. COUNT(siparis_sayisi) de 3'tür: Ayşe (3), Burak (0) ve Emre (5). Sıfır değeri sayıma girer.
Bir sütundaki eksik (NULL) değer sayısını bulmak için ikisinin farkını al:
SELECT COUNT(*) - COUNT(eposta) AS eksik_eposta
FROM musteriler;
eksik_eposta
2
Sonuç 2'dir ve yalnız NULL olan Burak ile Emre'yi yansıtır. Ceren'in boş metni bu hesapta eksik sayılmaz; onu da dahil etmek istiyorsan önceki bölümdeki IS NULL OR eposta = '' koşulunu kullan.
COALESCE ile eksik değere varsayılan değer atama
COALESCE(değer1, değer2, ...) verdiğin değerleri soldan sağa bakar ve ilk NULL olmayanı döndürür. Hepsi NULL ise sonuç da NULL olur. Standart SQL'de yer alan bir fonksiyondur ve NULL'ı çıktıda okunabilir bir değerle göstermek için kullanılır.
SELECT ad, COALESCE(eposta, 'e-posta yok') AS iletisim
FROM musteriler;
E-postası NULL olan satırlarda iletisim sütununda "e-posta yok" yazar:
ad | iletisim
--------+------------------
Ayşe | [email protected]
Mehmet | e-posta yok
Zeynep | [email protected]
Aynı mantık sayılarda da çalışır:
SELECT ad, COALESCE(siparis_sayisi, 0) AS siparis
FROM musteriler;
Burada NULL olan sipariş sayıları çıktıda 0 görünür. Tablodaki veri değişmez; COALESCE yalnızca sorgunun gösterdiği sonucu düzenler.
NULL'ı 0'a çevirmeden önce düşün
"Sipariş sayısı bilinmiyor" ile "hiç sipariş vermedi" aynı anlama gelmez. NULL'ı 0 olarak göstermek bu ayrımı raporda siler. Verinin eksik mi yoksa gerçekten sıfır mı olduğunu bilerek karar ver; emin değilsen NULL olarak bırakmak daha dürüst olabilir.
Bu tür kavramları okuyarak kalıcı hâle getirmek zor olabilir. Kendini test ederek pekiştirmek için ücretsiz bilgi testleri merkezindeki algoritmik düşünme ve programlama pratiği testlerine göz atabilirsin. Buradaki testler SQL'e değil, Python, Java, C# ve algoritmik düşünmeye yöneliktir; mantık kurma alışkanlığını geliştirmek için işe yarar.
Sıradaki küçük adım: kendi müşteri tablonda WHERE eposta IS NULL sorgusunu çalıştır, sonra aynı sütunu COALESCE ile göstererek iki çıktıyı yan yana karşılaştır.