---
title: 'Boş Değerlerle Çalışma'
source: 'https://academia.sh/tr/kurslar/sql-temelleri/bos-degerlerle-calisma'
course: 'SQL Temelleri'
language: tr
updated: '2026-08-17T18:09:02+00:00'
license: 'CC BY-SA 4.0'
---

# Boş Değerlerle Çalışma

Üç değerli mantığın sorgudaki sonuçları, boş değer sınamaları, boş değer yerine geçen işlevler, koşullu ifade ile boşluk doldurma ve liste koşulunun değillemesindeki tuzak.

Önceki üç ders boş değerle üç kez karşılaştı: hesaplanmış bir ifadeyi boşalttı, bir koşulun
değillemesini eksik bıraktı, sıralamada motora bağlı bir yer aldı. Her seferinde açıklama
ertelendi. Bu ders ertelenen açıklamayı yapar.

Boş değer (null) bir değer değil, **değerin yokluğunu** bildiren bir işarettir. Sıfır değildir,
boş dize değildir; "bu satır için bu bilgi yok" demektir. İlişkisel Kuram kursunda boş
değerin şemadaki anlamı tanımlanmıştı. Burada sorgudaki davranışı kurulur ve o davranış tek
bir kaynaktan çıkar: bilinmeyen bir değerle yapılan karşılaştırmanın sonucu da bilinmezdir.

Aşağıdaki blok şemayı ve örnek veriyi kurar; dersin bütün sorguları bu blokta oluşturulan
`kutuphane.db` dosyası üzerinde çalışır.

```sh
rm -f kutuphane.db
sqlite3 kutuphane.db <<'SQL'
CREATE TABLE sube (sube_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT NOT NULL);
CREATE TABLE kitap (kitap_id INTEGER PRIMARY KEY, baslik TEXT NOT NULL, yazar TEXT NOT NULL,
                    basim_yili INTEGER, sube_id INTEGER REFERENCES sube(sube_id));
CREATE TABLE uye (uye_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, soyad TEXT NOT NULL,
                  eposta TEXT, kayit_tarihi TEXT NOT NULL);
CREATE TABLE odunc (odunc_id INTEGER PRIMARY KEY, kitap_id INTEGER NOT NULL REFERENCES kitap(kitap_id),
                    uye_id INTEGER NOT NULL REFERENCES uye(uye_id), alis_tarihi TEXT NOT NULL,
                    iade_tarihi TEXT);
INSERT INTO sube VALUES (1,'Merkez','Ankara'),(2,'Bahçelievler','Ankara'),
  (3,'Kadıköy','İstanbul'),(4,'Konak','İzmir');
INSERT INTO kitap VALUES (1,'Körlük','José Saramago',1995,1),(2,'Tutunamayanlar','Oğuz Atay',1972,1),
  (3,'Kum Kitabı','Jorge Luis Borges',1975,2),(4,'Yaban','Yakup Kadri',1932,2),
  (5,'Sessiz Ev','Orhan Pamuk',1983,3),(6,'Anayurt Oteli','Yusuf Atılgan',NULL,3),
  (7,'Tehlikeli Oyunlar','Oğuz Atay',1973,NULL);
INSERT INTO uye VALUES (1,'Ayşe','Demir','ayse@ornek.test','2023-02-14'),
  (2,'Mehmet','Kaya','mehmet@ornek.test','2023-05-30'),(3,'Zeynep','Arslan',NULL,'2024-01-09'),
  (4,'Emre','Yıldız','emre@ornek.test','2024-03-22'),(5,'Selin','Aydın',NULL,'2024-11-05'),
  (6,'Burak','Şahin','burak@ornek.test','2025-01-18');
INSERT INTO odunc VALUES (1,1,1,'2025-01-10','2025-01-24'),(2,2,1,'2025-02-02','2025-02-20'),
  (3,1,2,'2025-02-11',NULL),(4,3,3,'2025-03-01','2025-03-15'),(5,4,3,'2025-03-18','2025-04-02'),
  (6,1,4,'2025-04-05','2025-04-19'),(7,5,4,'2025-04-21',NULL),(8,2,5,'2025-05-02','2025-05-30'),
  (9,7,1,'2025-05-14','2025-05-28'),(10,3,5,'2025-06-03',NULL),(11,6,2,'2025-06-11','2025-06-25'),
  (12,4,4,'2025-06-20','2025-07-04');
SQL
```

## Karşılaştırmanın Sonucu

Boş değerin eşitlik sınamasındaki davranışı doğrudan ölçülebilir.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT NULL = NULL AS esit, NULL <> NULL AS farkli, NULL IS NULL AS bos_mu;
SQL
```

```
esit  farkli  bos_mu
----  ------  ------
              1     
```

İlk iki sütun boş; üçüncüsü `1` yani doğru. Bir boş değer başka bir boş değere ne eşittir
ne de eşit değildir. İki bilinmeyen sayının birbirine eşit olup olmadığı bilinemez, çünkü
her ikisi de bilinmiyor. Eşitlik işleci bu durumda ne doğru ne yanlış üretir; üçüncü bir
mantıksal değer üretir: **bilinmeyen** (unknown).

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT 1 = 1 AS dogru, 1 = 2 AS yanlis, 1 = NULL AS bilinmiyor;
SQL
```

```
dogru  yanlis  bilinmiyor
-----  ------  ----------
1      0                 
```

Üç sütun mantığın üç değerini gösteriyor: doğru `1`, yanlış `0`, bilinmeyen ise boş.
`WHERE` yan tümcesinin yalnız doğruyu geçirdiği kuralı burada bir sonuca bağlanır: boş
değer içeren bir karşılaştırma hiçbir satırı geçirmez — ne koşulda, ne değillemesinde.

Boş değeri sınamanın tek doğru yolu `IS NULL` ve `IS NOT NULL` yazımlarıdır. Bunlar
karşılaştırma işleci değil, doğrudan boşluk sınayan yüklemlerdir ve her zaman doğru ya da
yanlış üretirler.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap WHERE basim_yili IS NULL;
SQL
```

```
baslik         basim_yili
-------------  ----------
Anayurt Oteli            
```

## Üç Değerli Mantık

Mantıksal bağlaçlar da üç değerle çalışır. Kural, bilinmeyeni "belki doğru belki yanlış"
diye okumaktır: sonuç her iki olasılıkta da aynıysa belirlenir, farklıysa bilinmeyen kalır.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT 1 AND NULL AS d_ve_b, 0 AND NULL AS y_ve_b, 1 OR NULL AS d_veya_b,
       0 OR NULL AS y_veya_b, NOT NULL AS degil_b;
SQL
```

```
d_ve_b  y_ve_b  d_veya_b  y_veya_b  degil_b
------  ------  --------  --------  -------
        0       1                          
```

İki sütun belirlendi. Yanlış ile bilinmeyenin `AND` bağlacı yanlıştır: bilinmeyen ne olursa
olsun sonuç yanlış. Doğru ile bilinmeyenin `OR` bağlacı doğrudur: bir taraf zaten doğru.
Kalan üçü bilinmeyen kaldı. Değilleme bilinmeyeni değiştirmez — bilinmeyenin tersi de
bilinmeyendir.

Bu tablo, Programlama Temelleri kursundaki kısa devre değerlendirme kuralının üç değerli
karşılığıdır: bir bağlacın sonucu bir taraftan belirlenebiliyorsa diğer taraf sonucu
etkilemez.

## Boş Değer Yerine Değer Koymak

Sonuç kümesinde boş yerine anlamlı bir değer göstermek için standart işlev `COALESCE`
kullanılır. Argümanlarını soldan sağa değerlendirir ve boş olmayan ilkini döndürür.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT ad, soyad, COALESCE(eposta,'(adres yok)') AS iletisim FROM uye;
SQL
```

```
ad      soyad   iletisim         
------  ------  -----------------
Ayşe    Demir   ayse@ornek.test  
Mehmet  Kaya    mehmet@ornek.test
Zeynep  Arslan  (adres yok)      
Emre    Yıldız  emre@ornek.test  
Selin   Aydın   (adres yok)      
Burak   Şahin   burak@ornek.test 
```

`COALESCE` ikiden çok argüman alabilir; öncelikli kaynaklardan ilk dolu olanı seçmek için
kullanılır. Birçok motor iki argümanlı bir kısaltma da sunar, ancak o kısaltmanın adı
**motora göre değişir**; taşınabilir yazım `COALESCE` yazımıdır.

Ters yönde çalışan işlev `NULLIF` iki argümanı karşılaştırır ve eşitlerse boş değer,
değilse birinci argümanı döndürür.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT ad, NULLIF(sehir,'Ankara') AS ankara_disi FROM sube ORDER BY sube_id;
SQL
```

```
ad            ankara_disi
------------  -----------
Merkez                   
Bahçelievler             
Kadıköy       İstanbul   
Konak         İzmir      
```

`NULLIF` en çok, anlamsız bir yer tutucuyu — sıfır, boş dize, `-1` — gerçek boş değere
çevirmek için işe yarar. Sıfıra bölmeyi engellemek de yaygın kullanımıdır: bölenin sıfır
olduğu durumda boş değer üretmek, hata almaktan daha yönetilebilirdir.

Boş değerin dönüştürülmesi koşullu ifadeyle de yazılabilir. `CASE` yapısı, bir sütunu
okunabilir bir duruma çevirmenin standart yoludur.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT odunc_id, alis_tarihi,
       CASE WHEN iade_tarihi IS NULL THEN 'dışarıda' ELSE 'iade edildi' END AS durum
FROM odunc WHERE odunc_id <= 4 ORDER BY odunc_id;
SQL
```

```
odunc_id  alis_tarihi  durum      
--------  -----------  -----------
1         2025-01-10   iade edildi
2         2025-02-02   iade edildi
3         2025-02-11   dışarıda   
4         2025-03-01   iade edildi
```

`CASE WHEN iade_tarihi = NULL` yazılsaydı hiçbir satır `dışarıda` olarak
etiketlenmezdi — koşul hiçbir zaman doğru olmazdı ve her satır `ELSE` dalına düşerdi. Bu,
boş değer hatalarının en sinsi biçimidir: sorgu hata vermez, yanlış cevap verir.

## Liste Koşulunun Değillemesi

Üç değerli mantığın en pahalı sonucu, liste koşulunun değillemesinde ortaya çıkar.
Kitapların bulunduğu şube kimlikleri `1`, `2` ve `3`; yedinci kitabın şubesi ise henüz
belirlenmemiş, yani boş. Hangi şubede hiç kitap olmadığını soran koşul önce boş değer
olmadan yazılsın.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT ad FROM sube WHERE sube_id NOT IN (1,2,3);
SQL
```

```
ad   
-----
Konak
```

Doğru yanıt: `Konak` şubesinde hiç kitap yok. Aynı liste, kitap tablosundaki değerlerden
üretilseydi içinde bir de boş değer bulunurdu. Bu durumda ne olduğu ölçülebilir.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT ad FROM sube WHERE sube_id NOT IN (1,2,3,NULL);
SELECT 'dönen satır sayısı: ' || COUNT(*) AS olcum
FROM sube WHERE sube_id NOT IN (1,2,3,NULL);
SQL
```

```
olcum                
---------------------
dönen satır sayısı: 0
```

Birinci sorgu hiçbir satır yazdırmadı; ikincisi bunu sayarak doğruladı. Tek bir boş değer,
sorgunun **hiçbir satır döndürmemesine** yol açtı ve hata
verilmedi. Nedeni doğrudan üç değerli mantıktan gelir: `NOT IN` koşulu, "listedeki her
öğeye eşit değil" biçiminde açılır. `4 <> 1 AND 4 <> 2 AND 4 <> 3 AND 4 <> NULL` ifadesinin
son çarpanı bilinmeyendir; doğru ile bilinmeyenin `AND` bağlacı da bilinmeyendir. Koşul
hiçbir satır için doğru olmaz.

Aynı liste olumlu yönde kullanıldığında sorun görünmez.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT ad FROM sube WHERE sube_id IN (1,2,3,NULL);
SQL
```

```
ad          
------------
Merkez      
Bahçelievler
Kadıköy     
```

`IN` koşulu `OR` ile açıldığı için, bir taraf doğru olduğunda bilinmeyen sonucu etkilemez.
Tuzak yalnızca değillemededir ve bu asimetri, hatanın gözden kaçmasının başlıca nedenidir:
olumlu sorgu doğru çalıştığı için değillemesinin de doğru çalıştığı varsayılır.

Korunma yolu, listeyi üreten kaynakta boş değerleri elemek ya da koşulu boş değere
duyarsız bir yüklemle yazmaktır. Standartta bunun için `IS DISTINCT FROM` yüklemi vardır;
boş değerleri de karşılaştırılabilir sayar.

```sh
sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT 1 IS DISTINCT FROM NULL AS bir_ve_bos,
       NULL IS DISTINCT FROM NULL AS bos_ve_bos,
       NULL IS NOT DISTINCT FROM NULL AS bos_bosa_esit;
SQL
```

```
bir_ve_bos  bos_ve_bos  bos_bosa_esit
----------  ----------  -------------
1           0           1            
```

Üç sütun da doğru ya da yanlış üretti; hiçbiri bilinmeyen değil. `IS DISTINCT FROM`
yükleminin desteği **motora göre değişir**; bulunmayan motorlarda aynı etki, boşluk
sınamasını koşula açıkça eklemekle sağlanır.

Boş değerlerin toplama işlevlerindeki davranışı da ayrı bir kural izler ve ikinci konuda
ölçülecek: toplama işlevleri boş değerleri sayıma katmaz.

## Özet

- Boş değer, değerin yokluğunu bildiren bir işarettir; sıfır ya da boş dize değildir.
- Boş değerle yapılan karşılaştırma ne doğru ne yanlış, bilinmeyen üretir; `WHERE` yalnız
  doğruyu geçirdiği için hem koşul hem değillemesi satırı eler.
- Boşluk yalnız `IS NULL` ve `IS NOT NULL` ile sınanır.
- `COALESCE` boş olmayan ilk argümanı, `NULLIF` eşitlik durumunda boş değer döndürür;
  `CASE` içinde boşluk sınaması eşitlikle değil `IS NULL` ile yazılır.
- `NOT IN` listesinde tek bir boş değer, sorgunun hata vermeden sıfır satır döndürmesine
  yol açar; aynı liste `IN` ile kullanıldığında sorun görünmez.
- `IS DISTINCT FROM` boş değere duyarsız karşılaştırma sağlar, desteği motora bağlıdır.

## Sonraki Adım

Bu derste `COALESCE`, `NULLIF` ve `CASE` yapıları boş değer bağlamında kullanıldı; oysa
üçü de daha geniş bir ailenin üyesidir. Sorgu, sütun değerlerini olduğu gibi göstermek
zorunda değil — metni kesebilir, sayıyı yuvarlayabilir, tarihten yıl çıkarabilir. Sonraki
ders dizgi, sayı ve tarih işlevlerini ele alır ve tarih işlevlerinin adlandırmasının neden
standardın en zayıf uygulandığı alan olduğunu gösterir.
