Menu

SQLite LEFT JOIN Kullanımı: Sol Tablodaki Tüm Satırlar

SQLite'ta LEFT JOIN nasıl çalışır? Eşleşmeyen satırları koruma, NULL değerleri okuma, WHERE ile güvenli filtreleme ve birden fazla tabloyu birleştirme.

Bu sayfada çalıştırılabilir editörler var — düzenle, çalıştır ve sonucu anında gör.

LEFT JOIN Soldaki Her Şeyi Korur

INNER JOIN yalnızca iki tarafın da eşleştiği satırları döndürür. Çoğu zaman istediğiniz şey budur, ama her zaman değil. Bazen aradığınız cevabın kendisi "eşleşme yok" durumudur: hiç sipariş vermemiş kullanıcılar, hiç satılmamış ürünler, henüz yorum almamış gönderiler. İşte tam bu noktada LEFT JOIN devreye girer.

LEFT JOIN, soldaki tablonun tüm satırlarını döndürür. Sağdaki tabloda eşleşen bir satır varsa, eşleşen sütunları da alırsınız. Yoksa sol taraftaki satır yine gelir; sağ taraftaki sütunlar ise NULL olarak döner.

Cleo'nun hiç siparişi yok ama yine de listede görünüyor — total sütununda NULL ile. LEFT JOIN yerine INNER JOIN yazarsanız Cleo bir anda kayboluveriyor.

Mantığı Kafanızda Nasıl Kurmalısınız?

Sorguyu yukarıdan aşağıya okurken sol tabloyu çapa olarak düşün. users tablosundaki her satır, ne olursa olsun çıktıda yer alacak. LEFT JOIN de her kullanıcı için şunu soruyor: "orders tablosunda buna karşılık gelen bir satır var mı?"

  • Eşleşme bulundu → eşleşen sütunlar kullanıcı satırına yapıştırılır.
  • Birden fazla eşleşme var → her eşleşme için ayrı bir satır üretilir (Ada'nın iki siparişi var, bu yüzden iki kez görünüyor).
  • Eşleşme yok → sağ taraftaki tablonun tüm sütunları NULL olan tek bir satır üretilir.

İşte bu son durum, LEFT JOIN'in var olma sebebidir. Buradaki NULL, "bilmiyoruz" anlamına gelmez — "sağ tarafta yapıştıracak hiçbir şey yok" demektir.

LEFT OUTER JOIN da aynı işi yapar. SQLite'ta OUTER anahtar kelimesi isteğe bağlıdır ve çoğu kişi onu yazma zahmetine bile girmez.

Eşleşmeyen Satırları Bulma

Klasik LEFT JOIN senaryosu: sol tabloda sağ tarafta hiç karşılığı olmayan satırları bulmak. İşin püf noktası şu: join sonrası, sağ tablodaki gerçek veride NOT NULL olan bir sütun üzerinden filtre yapmak — genellikle birincil anahtar — ve sonra NULL kontrolü yapmak:

Sonuçta yalnızca Cleo döner. JOIN mevcut sipariş verisini ekler; ardından WHERE o.id IS NULL koşulu da yalnızca eşleşmenin başarısız olduğu satırları bırakır. Bu kalıba bazen "anti-join" da denir.

ON ile WHERE farkı: Gözden kaçan tuzak

LEFT JOIN ile en sık karşılaşılan hata tam da burada başlıyor, o yüzden biraz duralım. Koşulları ister ON ister WHERE yan tümcesine yazabilirsiniz; ama dış birleşimlerde (outer join) bu ikisi bambaşka şekilde çalışır.

  • ON, birleşim gerçekleşirken devreye girer. Buradaki koşullar, sağdaki hangi satırların eşleşme sayılacağını belirler.
  • WHERE ise birleşim satırları üretildikten sonra çalışır. Yani birleştirilmiş sonucu filtreler.

Sağdaki tabloya ait bir koşulu WHERE içine koyduğunuzda neler olduğuna bakın:

Cleo'nun hiçbir siparişi olmadığı için onun satırında o.status değeri NULL oluyor; NULL = 'shipped' ifadesi de doğru sonuç vermediğinden Cleo sonuç kümesinden eleniyor. Boris'in durumu ise 'pending' olduğu için o da listeden düşüyor. Sonuç olarak LEFT JOIN sessiz sedasız bir INNER JOIN gibi davranmış oluyor.

Çözüm basit: koşulu ON kısmına taşıyın. Böylece koşul çıktı satırlarını değil, eşleşmeleri filtrelemiş olur:

Artık her kullanıcı görünüyor. Ada'nın kargoya verilmiş siparişi geliyor; Boris için NULL dönüyor (bekleyen siparişi eşleşme sayılmadı); Cleo için de NULL (zaten hiç siparişi yok). "Bana tüm kullanıcıları göster, varsa kargolanmış siparişleriyle birlikte" diye sorduğunuzda doğru cevap budur.

Pratik kural: sol tablodaki koşullar WHERE içinde durabilir. Sağ tablodaki koşullar ise neredeyse her zaman ON içine yazılmalıdır — tek istisna, IS NULL ile eşleşmeyen satırları bulmak istediğiniz durumdur.

LEFT JOIN ile Sayma İşlemi

Sık karşılaşılan bir senaryo: her ana kayıt için ilişkili satırları saymak, hatta hiç ilişkili satırı olmayanları bile dahil ederek. INNER JOIN kullanırsanız sıfır olanlar listeden düşer. LEFT JOIN ile birlikte sağ taraftaki bir sütunun COUNT'unu almak doğru sonucu verir:

Dikkat çekmek istediğim iki nokta var:

  • COUNT(o.id) sağ taraftaki null olmayan satırları sayar. Cleo 1 değil 0 alır — çünkü COUNT, NULL değerleri görmezden gelir. COUNT(*) yazsaydınız Cleo 1 alırdı (satır var, sadece içi NULL dolu). Neredeyse her zaman istediğiniz şey COUNT(right.id) kalıbıdır.
  • COALESCE(SUM(o.total), 0), Cleo'nun NULL toplamını 0'a çevirir. Bu olmadan ciroda NULL görünür; teknik olarak doğru ama ekranda hoş durmaz.

Birden Fazla Tabloyla LEFT JOIN Kullanımı

LEFT JOIN zincirlenebilir. Her join, mevcut sonuca yeni bir tablo ekler. Bir sütunu LEFT JOIN ile nullable hâle getirdikten sonra, ona bağlı tüm tablolar için de LEFT JOIN kullanmaya devam edin — aksi takdirde sonraki bir INNER JOIN, korumak istediğiniz satırları sessizce kırpıp atar.

Üç kullanıcı geri döndü. Ada'nın hem siparişi hem de gönderisi var. Boris'in siparişi var ama gönderisi yok (yani carrier değeri NULL). Cleo'nun ise hiç siparişi olmadığı için hem o.total hem de s.carrier NULL olarak geliyor. Peş peşe gelen LEFT JOIN'ler sayesinde, ilişki zincirinin neresinde veri biterse bitsin tüm kullanıcılar sonuçta kalmaya devam ediyor.

SQLite LEFT JOIN ne zaman doğru tercihtir?

Sorunun özü sol tablo etrafında dönüyorsa ve sağ tablo yalnızca tamamlayıcı bilgi sağlıyorsa LEFT JOIN kullanın. "Tüm kullanıcılar, varsa siparişleriyle birlikte" ya da "tüm ürünler ve son yorumları" gibi ifadeler doğrudan LEFT JOIN ile karşılık bulur.

İki tarafın da zorunlu olduğu durumlarda ise INNER JOIN'e başvurun. Örneğin "siparişler ve kullanıcı bilgileri" sorgusunda kullanıcısız bir siparişin anlamı yoktur; bu yüzden inner join'in filtreleme davranışı tam olarak istediğiniz şeydir.

Eğer kendinizi LEFT JOIN ... WHERE right.col IS NOT NULL yazarken bulursanız, aslında istediğiniz şey INNER JOIN'di. Ama LEFT JOIN ... WHERE right.col IS NULL yazıyorsanız, bu bir anti-join'dir ve bilerek doğru olanı yapıyorsunuzdur.

Sırada: Self-Join'ler

Bazen birleştirmek istediğiniz tablo, zaten sorguladığınız tablonun ta kendisidir — çalışanlar ve yöneticileri, kategoriler ve üst kategorileri, aynı şehirdeki kullanıcı çiftleri gibi. İşte buna self-join deniyor ve bir sonraki sayfanın konusu bu.

Sıkça Sorulan Sorular

SQLite'ta LEFT JOIN ne işe yarar?

LEFT JOIN, sol tablodaki tüm satırları döndürür; sağ tabloda eşleşme varsa onu da yanına ekler. Sağ tarafta eşleşme yoksa sol satır yine gelir, ama sağ taraftaki sütunlar NULL olarak görünür. LEFT OUTER JOIN ile aynı şeydir; SQLite'ta OUTER anahtar kelimesi isteğe bağlıdır.

SQLite'ta LEFT JOIN ile INNER JOIN arasındaki fark nedir?

INNER JOIN yalnızca iki tabloda da eşleşen satırları getirir. LEFT JOIN ise sol tablonun tüm satırlarını getirir; eşleşme olmayan sağ taraf sütunlarını NULL ile doldurur. 'Eşleşme yok' bilgisinin kendisi anlamlıysa — örneğin hiç sipariş vermemiş kullanıcıları bulmak gibi — LEFT JOIN kullanmalısın.

LEFT JOIN'im neden INNER JOIN gibi davranıyor?

Genellikle sebebi şu: WHERE koşulunda sağ tablodaki bir sütunu NULL ihtimalini hesaba katmadan filtreliyorsun. Sağ tabloya ait koşullar WHERE yerine ON içine yazılmalı; ya da eşleşmeyen satırları yakalamak için WHERE sag.kolon IS NULL yazman gerekir. Çünkü WHERE sag.kolon = 'x' yazdığında eşleşmeyen tüm satırlar sessizce elenir.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA