- Konu sahibi
- #1
SQL JOIN türleri arasındaki fark nedir?
SQL JOIN türleri, iki veya daha fazla tablodaki satırların hangi koşulla eşleştirileceğini ve eşleşmeyen satırların sonuçta tutulup tutulmayacağını belirler. INNER JOIN yalnızca eşleşenleri, LEFT JOIN sol tablonun tamamını, RIGHT JOIN sağ tablonun tamamını, FULL OUTER JOIN ise her iki tablonun tamamını getirir. CROSS JOIN ise satırları eşleştirme koşulu olmadan tüm kombinasyonlarıyla birleştirir.
Örnek olarak aşağıdaki iki tabloyu düşünelim:
Kod:
musteriler
id | ad
1 | Ayşe
2 | Bora
3 | Ceren
siparisler
id | musteri_id | tutar
10 | 1 | 250
11 | 1 | 100
12 | 4 | 500
Bu örnekte Ayşe'nin iki siparişi vardır, Bora ve Ceren'in siparişi yoktur. Bu sentetik veri yabancı anahtar denetimi uygulamayan bir örnektir. 4 numaralı müşteri ise
musteriler tablosunda bulunmadığı için yetim bir sipariş satırıdır. JOIN türlerinin sonucu bu farklara göre değişir.JOIN türlerini karşılaştırma
Aşağıdaki tablo, eşleşmeyen satırların nasıl ele alındığını gösterir.
| JOIN türü | Sonuçta tutulan satırlar | Tipik kullanım |
|---|---|---|
| INNER JOIN | Her iki tabloda eşleşenler | Yalnız ilişkili kayıtları listelemek |
| LEFT JOIN | Sol tablonun tamamı ve eşleşen sağ kayıtlar | Kayıtlı olmayan ilişkileri bulmak |
| RIGHT JOIN | Sağ tablonun tamamı ve eşleşen sol kayıtlar | LEFT JOIN'in tablo yönü değiştirilmiş biçimi |
| FULL OUTER JOIN | Her iki tablodaki tüm satırlar | Eksik veya eşleşmeyen kayıtları iki tarafta da görmek |
| CROSS JOIN | Tüm satır kombinasyonları | Kombinasyon veya seçenek matrisi oluşturmak |
Tablodaki “sol” ve “sağ” ifadeleri sorgudaki tablo sırasını belirtir.
FROM musteriler m LEFT JOIN siparisler s yazıldığında musteriler sol tablodur. Bir müşterinin siparişi yoksa sipariş sütunları NULL olur.Sorgularla somut farklar
Sorgular için iki tablonun ve gösterilen sütunların önceden oluşması gerekir. MySQL doğrudan FULL OUTER JOIN desteklemediğinden son örnek UNION ALL ile yalnız ikinci tarafın eşleşmeyenlerini ekler; böylece eşleşen satırlar iki kez eklenmez:
Kod:
-- Yalnız siparişi olan müşteriler
SELECT m.ad, s.tutar
FROM musteriler AS m
INNER JOIN siparisler AS s ON s.musteri_id = m.id;
-- Tüm müşteriler; siparişi olmayanlarda s sütunları NULL olur
SELECT m.ad, s.tutar
FROM musteriler AS m
LEFT JOIN siparisler AS s ON s.musteri_id = m.id;
-- Siparişi olmayan müşteriler
SELECT m.ad
FROM musteriler AS m
LEFT JOIN siparisler AS s ON s.musteri_id = m.id
WHERE s.id IS NULL;
-- MySQL için FULL OUTER JOIN sonucunu eşleşmeyenlerle kurma
SELECT m.ad, s.id AS siparis_id
FROM musteriler AS m
LEFT JOIN siparisler AS s ON s.musteri_id = m.id
UNION ALL
SELECT m.ad, s.id AS siparis_id
FROM siparisler AS s
LEFT JOIN musteriler AS m ON m.id = s.musteri_id
WHERE m.id IS NULL;
İlk sorgu yalnız Ayşe'nin iki siparişini döndürür. İkinci sorgu Ayşe'yi iki satırla, Bora ve Ceren'i ise
NULL sipariş bilgileriyle gösterir. Üçüncü sorgu, ilişkili kaydı olmayan müşterileri bulur. Dördüncü sorgu ise Bora ve Ceren gibi siparişi olmayan müşterilerle birlikte müşteri kimliği 4 olan, id=12 siparişi de gösterir.Hangi JOIN seçilmeli?
- Sonuçta yalnız iki tabloda da karşılığı bulunan kayıtlar gerekiyorsa
INNER JOINkullanın. - Ana listenin hiçbir satırını kaybetmemesi gerekiyorsa ana tabloyu sola yazıp
LEFT JOINkullanın. Örneğin tüm müşterileri, siparişi olmayanlar dahil, listelemek için bu seçim uygundur. - Sağ tablodaki tüm kayıtları korumak istiyorsanız tablo sırasını değiştirerek çoğu durumda aynı sonucu
LEFT JOINile daha okunaklı yazabilirsiniz.RIGHT JOINzorunlu değildir. - İki taraftaki eksik ilişkileri birlikte denetlemek gerekiyorsa
FULL OUTER JOINseçin. Veritabanınız bu türü desteklemiyorsa aynı amaç UNION tabanlı bir sorguyla kurulabilir; sözdizimi veritabanına göre değişir. - Her satırı her satırla birleştirmek gerçekten amaçlanmıyorsa
CROSS JOINkullanmayın. Satır sayısı iki tablonun satır sayılarının çarpımına ulaşabilir.
Sık yapılan hatalar
LEFT JOIN'i WHERE koşuluyla INNER JOIN'e çevirmek
LEFT JOIN ile alınan sağ tablo sütununu WHERE s.durum = 'A' gibi bir koşulla süzmek, NULL satırları dışarıda bırakır ve sorguyu pratikte INNER JOIN davranışına yaklaştırır. Sağ tablo koşulunun eşleşme sırasında uygulanması gerekiyorsa çoğu durumda koşulu ON bölümüne taşıyın.JOIN koşulunu eksik yazmak
ON koşulu yanlış veya eksik olursa istenmeyen satır çoğalması oluşabilir. İlişki sütunlarını açıkça yazın, aynı isimli sütunlarda tablo takma adları kullanın ve beklenen satır sayısını kontrol edin.Çoğalmayı yanlış yorumlamak
Bir müşterinin birden fazla siparişi varsa müşteri satırının birden fazla görünmesi JOIN hatası değildir; ilişki bire-çoktur. Tek satır istiyorsanız amacınıza göre
GROUP BY, toplama işlevi veya EXISTS kullanmanız gerekir.Sık sorulan sorular
JOIN yazarken INNER veya OUTER belirtmek zorunlu mu?
Hayır.
JOIN tek başına yazıldığında genellikle INNER JOIN anlamına gelir. Okunabilirlik için türü açıkça yazmak daha güvenlidir.INNER JOIN ile WHERE koşulu arasındaki fark nedir?
JOIN, tabloların hangi ilişkiyle birleştirileceğini belirler; WHERE ise oluşan sonucu filtreler. Ancak dış JOIN'lerde koşulun
ON veya WHERE bölümünde olması, eşleşmeyen satırların korunup korunmamasını değiştirebilir.FULL OUTER JOIN her SQL veritabanında çalışır mı?
Hayır. JOIN türlerinin desteklenmesi ve eksik türleri yazma yöntemi kullanılan veritabanı ürününe göre değişebilir. Sorguyu çalıştırmadan önce hedef sistemin JOIN sözdizimini kontrol edin.