SQL LEFT JOIN ile Eşleşmeyen Kayıtlar Nasıl Bulunur? Bunun için sol tablodaki tüm kayıtları koruyan LEFT JOIN kullanılır. Eşleşme bulunmayan satırları seçmek için de sağ tablonun birincil anahtarı gibi NULL kabul etmeyen bir alan, WHERE koşulunda IS NULL ile filtrelenir.
İşleyiş kısaca şöyledir: LEFT JOIN önce sol tablodaki satırları sonuçta tutar. ON koşuluna göre sağ tabloda eşleşme bulunursa sağ sütunları ilgili değerlerle doldurur, eşleşme bulunamazsa sağ tabloya ait sütunları NULL olarak üretir. Ardından IS NULL koşulu, bu eşleşmeyen satırları ayıklar.
Çözümün temeli: LEFT JOIN sonrası sağ anahtarı IS NULL ile filtrelemek
Eşleşmeyen kayıtları bulurken filtre için sağ tablonun birincil anahtarını veya şemada NULL kabul etmeyen bir kimlik alanını seçmek gerekir. Örneğin sipariş tablosundaki id alanı, her gerçek sipariş için değer taşıyorsa güvenilir bir seçimdir. Eşleşme olmadığında siparisler.id değeri NULL üretileceği için WHERE s.id IS NULL koşulu, siparişi olmayan müşterileri bulabilir.
NULL değerleri normal eşitlik operatörüyle karşılaştırılmaz. Bu nedenle s.id = NULL yerine s.id IS NULL yazılır. Nullable, yani kendisi de NULL olabilen bir alanı filtre olarak seçmek ise eşleşen bazı satırların yanlışlıkla eşleşmemiş kabul edilmesine yol açabilir. Bu alan seçiminin sonuçları nasıl etkilediğini ilerleyen bölümde kontrol edeceğiz.
Müşteriler ve siparişler örneği: sorgu ve beklenen sonuç

Aşağıdaki örnekte sol tablo musteriler, sağ tablo ise siparisler tablosudur. Müşteri ile sipariş arasındaki anahtar ilişkisi musteriler.id = siparisler.musteri_id şeklindedir. ON koşulu bu ilişkiyi kurar ve hangi siparişin hangi müşteriye ait olduğunu belirler.
musteriler tablosu:
| id | ad |
|---|---|
| 1 | Ada |
| 2 | Bora |
| 3 | Ceren |
| 4 | Deniz |
siparisler tablosu:
| id | musteri_id |
|---|---|
| 101 | 1 |
| 102 | 1 |
| 103 | 3 |
Müşterisi olmayan siparişleri değil, sipariş vermemiş müşterileri bulmak için sorgu şöyledir:
SELECT m.id, m.ad, s.id AS siparis_id
FROM musteriler AS m
LEFT JOIN siparisler AS s ON m.id = s.musteri_id
WHERE s.id IS NULL
ORDER BY m.id;
Bu sorguda LEFT JOIN bütün müşterileri korur. Ada'nın iki siparişi olduğu için filtre uygulanmadan önce ham join sonucunda iki ayrı satırda görünür. Ceren'in bir siparişi bulunduğundan bir eşleşme satırı oluşur. Bora ve Deniz için sağ tabloda eşleşen sipariş bulunmadığından s.id değeri NULL olur. WHERE s.id IS NULL koşulu uygulandığında beklenen çıktı aşağıdaki gibi kalır:
| id | ad | siparis_id |
|---|---|---|
| 2 | Bora | NULL |
| 4 | Deniz | NULL |
Burada ON eşleşmenin nasıl kurulacağını, WHERE ise join tamamlandıktan sonra hangi sonuçların tutulacağını belirler. Bu ayrımı doğru kurmak, sonraki filtrelerin eşleşmeyen kayıtları yanlışlıkla elemesini önlemek için önemlidir.
ON ve WHERE farkı: eşleşmeyen satırları yanlışlıkla eleme

ON koşulu, iki tablonun hangi anahtarlarla eşleşeceğini ve hangi kayıtların eşleşme adayı olacağını tanımlar. WHERE koşulu ise JOIN işleminden sonra oluşan sonuç kümesini filtreler. Bu ayrımı gözden kaçırmak, LEFT JOIN ile korunması gereken sol tablo kayıtlarının elenmesine yol açabilir.
Tamamlanmış siparişi olmayan müşterileri bulmaya çalışırken aşağıdaki yaklaşım hatalıdır:
SELECT m.id, m.ad
FROM musteriler AS m
LEFT JOIN siparisler AS s
ON m.id = s.musteri_id
WHERE s.durum = 'tamamlandi';
Bu sorgu, tamamlanmış siparişi bulunan müşterileri getirir. Siparişi olmayan bir müşteri için sağ tablodan gelen sütunlar NULL olur. s.durum = 'tamamlandi' karşılaştırması NULL değerlerde doğru kabul edilmediği için bu müşteriler sonuçtan çıkarılır. Böylece sorgu, bu koşul bakımından INNER JOIN davranışına yaklaşır.
Amaç tamamlanmış siparişi olmayan müşterileri bulmaksa, durum koşulunu ON içine taşıyıp sağ tablonun birincil anahtarını kontrol etmelisin:
SELECT m.id, m.ad
FROM musteriler AS m
LEFT JOIN siparisler AS s
ON m.id = s.musteri_id
AND s.durum = 'tamamlandi'
WHERE s.id IS NULL;
Bu sorgu, tamamlanmış siparişi bulunmayan müşterileri bırakır. Hiç sipariş vermemiş müşterileri arıyorsan s.durum koşulunu tamamen kaldırıp yalnızca müşteri anahtarıyla eşleştirme yapmalısın. Koşul ve ilişki mantığını adım adım pekiştirmek için Algoritmik Düşünme Testi de yararlı bir alıştırma sunabilir.
- Sol tabloda korunacak kayıt kümesini belirle. Örneğin, sonuçta bütün müşterilerin değerlendirilip değerlendirilmeyeceğini netleştir.
ONiçindeki anahtar çiftini ve yönünü doğrula. Bu örnekte ilişkim.id = s.musteri_idbiçimindedir.WHEREolmadan hamLEFT JOINsonucunu incele ve eşleşen kayıtların nasıl çoğaldığını gözlemle.- Sağ tarafta
NULLolamayacak bir alan seç. Genellikle birincil anahtar olans.idgüvenli bir kontroldür. WHEREkoşullarını tek tek ekleyip satır sayısını ve örnek kimlikleri karşılaştır.- Bilinen eşleşen ve eşleşmeyen kayıtlarla son testi yap. Böylece hem anahtar ilişkisini hem de filtre mantığını birlikte doğrulayabilirsin.
NULL alanlar ve tekrarlanan siparişlerle sonucu doğrulama
Eşleşme kontrolünde, sağ tablonun her zaman dolu olması beklenmeyen alanlarını kullanma. Örneğin teslim tarihi daha sonra yazılabilen bir sipariş için s.teslim_tarihi değeri NULL olabilir. WHERE s.teslim_tarihi IS NULL filtresi bu siparişi, müşteri hiç sipariş vermemiş gibi gösterebilir.
Bu nedenle eşleşme testi için sağ tablonun birincil anahtarını veya şema gereği NULL olamayan kimlik alanını kullan. Bir müşterinin birden fazla siparişi varsa LEFT JOIN her eşleşme için ayrı bir satır üretir. Anti-join filtresi olan s.id IS NULL ise yalnızca hiç eşleşmesi bulunmayan müşterinin sağ tarafı NULL ile doldurulmuş satırını bırakır.
SELECT m.id, m.ad, COUNT(s.id) AS siparis_sayisi
FROM musteriler AS m
LEFT JOIN siparisler AS s ON m.id = s.musteri_id
GROUP BY m.id, m.ad
ORDER BY m.id;
Örnek veriye göre bu sorguda Ada için 2, Bora için 0, Ceren için 1 ve Deniz için 0 eşleşme beklenir. Burada COUNT(s.id), yalnızca gerçekten eşleşen siparişlerin kimliklerini sayar. COUNT(*) ise sol tablodaki korunmuş satırı da saydığı için siparişi olmayan bir müşteri için 1 döndürebilir.
Sonucu doğrulamak için önce beklenen kayıt kümesini ve satır sayısını çıkar; sonra sorgu sonucundaki kimliklerle karşılaştır; son olarak birkaç örnek kaydı ve NULL olabilen alanları ayrı kontrol et.
Uygulama sonunda kullanabileceğin SQL kontrol listesi
Bir LEFT JOIN sorgusunun doğru sonuç verdiğini anlamak için yalnızca sorgunun çalışmasına bakma. Eşleşme mantığını, NULL davranışını ve sonuç kümesindeki satır sayısını birlikte kontrol et.
- Aradığın eşleşmeyen kayıtların gerçekten sol tabloda bulunduğunu ve sorguda sol tablo olarak seçildiğini doğrula.
ONkoşulunda doğru anahtar çiftinin, yani ilişkili tabloları bağlayan alanların kullanıldığını kontrol et.IS NULLuygulanan sağ taraf alanınınNULLkabul etmeyen, tercihen sağ tablonun anahtar alanı olduğunu doğrula.- Sağ tabloya ait
WHEREkoşullarının, eşleşmeyen satırları oluşanNULLdeğerler nedeniyle istemeden elemediğini incele. - Bir sol kayda birden fazla sağ kayıt eşleşiyorsa satır tekrarının beklenen bir sonuç olup olmadığını değerlendir.
- Beklenen eşleşmeyen satır sayısını, sorgunun ürettiği gerçek satır sayısıyla karşılaştır.
- Birkaç örnek kimliği elle doğrula ve bu kayıtların sol tabloda bulunduğunu, sağ tabloda ise beklenen eşleşmenin olmadığını kontrol et.
SQL sorgularındaki koşul ve ilişki mantığını genel yazılım temelleriyle birlikte değerlendirmek istersen, ücretsiz bilgi testleri merkezi içindeki ilgili testleri bir başlangıç noktası olarak kullanabilirsin.
Özetle, LEFT JOIN ile sol tabloyu koru ve eşleşmeyen kayıtları sağ tablonun NULL olamayacak anahtarını IS NULL ile filtreleyerek ayır.
Sık Sorulan Sorular
SQL LEFT JOIN ile eşleşmeyen kayıtları bulurken neden sağ tablonun id alanı IS NULL kontrol edilir?
LEFT JOIN eşleşme bulamadığında sağ tabloya ait alanları NULL olarak gösterir. Sağ tablonun birincil anahtarı gibi NULL kabul etmeyen bir alan kontrol edildiğinde, bu değer gerçekten NULL ise sağ tabloda eşleşen bir satır bulunmadığı anlaşılır.
WHERE koşulunu sağ tabloya yazmak LEFT JOIN sonucunu neden değiştirebilir?
Eşleşmeyen satırlarda sağ tablo alanları NULL olduğu için sağ tabloya ait bir koşul bu satırları elleyebilir. Böylece sorgu, eşleşmeyen kayıtları korumak yerine pratikte yalnızca eşleşen satırları döndüren bir yapıya yaklaşır.
Bir müşterinin birden fazla siparişi varsa LEFT JOIN sonucu neden tekrarlanır?
Bir müşteriyle eşleşen her sipariş için ayrı bir sonuç satırı oluşturulur. Bu nedenle aynı müşteri bilgisi birden fazla kez görünebilir. Aradığın sonuç müşteri bazında tek satırsa tekrarları nasıl ele alacağını ayrıca belirlemelisin.
Sağ tablodaki seçtiğim alan NULL olabiliyorsa hangi alanı kontrol etmeliyim?
Eşleşme göstergesi olarak, sağ tabloda her gerçek kayıt için mutlaka dolu olan bir alanı seçmelisin. Genellikle birincil anahtar bu amaçla kullanılır. Değerinin kendisi NULL olabilen bir sütun, eşleşme yokluğu ile eşleşen kayıttaki boş değeri ayırt etmeyebilir.
Doğru anahtar, doğru ON koşulu ve güvenilir bir sağ taraf IS NULL kontrolü, eşleşmeyen kayıt sorgularının temelini oluşturur.