← Kursa Dön
📄 Text · 35 min

JOIN Kavramı ve Türleri — Genel Bakış

Giriş — Neden Tablolar Birleştirilir?

İlişkisel veritabanlarında veriler farklı tablolara dağılmıştır: müşteri bilgileri customers tablosunda, sipariş bilgileri orders tablosunda, ürün bilgileri products tablosunda... Ama "Ali Yılmaz'ın sipariş ettiği ürünlerin isimleri ve fiyatları" gibi bir soruyu cevaplamak için bu tabloları birleştirmemiz gerekir.

İşte JOIN tam olarak bu işi yapar — birden fazla tabloyu ortak sütunlar üzerinden birleştirir.

🎯 Analoji: JOIN, bir bulmacadaki parçaları birleştirmek gibidir. Her tablo bir bulmaca parçası ve birleştirme noktaları yabancı anahtarlar (foreign key). Doğru parçaları doğru noktalardan birleştirdiğinde büyük resim ortaya çıkar.

JOIN Türleri — Genel Bakış

         ┌─────────────┐
         │             │
    ┌────┤ INNER JOIN  ├────┐
    │    │ (kesişim)   │    │
    │    └──────┬──────┘    │
    │           │           │
┌───┴───┐  ┌───┴───┐  ┌───┴───┐
│  LEFT │  │ FULL  │  │ RIGHT │
│  JOIN │  │ OUTER │  │  JOIN │
│ (sol) │  │ JOIN  │  │ (sağ) │
└───────┘  └───────┘  └───────┘
    
    ┌───────────┐  ┌───────────┐
    │  CROSS    │  │   SELF    │
    │   JOIN    │  │   JOIN    │
    │(kartezyen)│  │(kendine)  │
    └───────────┘  └───────────┘
JOIN TürüAçıklamaNe Döndürür
INNER JOINHer iki tabloda eşleşen satırlarSadece eşleşenler
LEFT JOINSol tablodaki tüm satırlar + eşleşenlerSol tablo tam, sağ kısmi
RIGHT JOINSağ tablodaki tüm satırlar + eşleşenlerSağ tablo tam, sol kısmi
FULL OUTER JOINHer iki tablodaki tüm satırlarHer ikisi tam
CROSS JOINKartezyen çarpım — her satır × her satırTüm kombinasyonlar
SELF JOINTablo kendisiyle birleşirHiyerarşi, karşılaştırma

JOIN Söz Dizimi

SELECT t1.sutun, t2.sutun
FROM tablo1 AS t1
[INNER | LEFT | RIGHT | CROSS] JOIN tablo2 AS t2
    ON t1.ortak_sutun = t2.ortak_sutun
WHERE kosul;

Temel kurallar:

  1. FROM ile ilk tabloyu belirt

  2. JOIN ile ikinci tabloyu belirt

  3. ON ile birleştirme koşulunu yaz

  4. Tablo alias'ları kullan — sorguyu kısaltır

İlk JOIN Sorgusu

-- Siparişleri müşteri adıyla birlikte göster
SELECT 
    o.order_id,
    c.first_name,
    c.last_name,
    o.order_date,
    o.total_amount,
    o.status
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id
ORDER BY o.order_date DESC;

Bu sorgu:

  1. orders ve customers tablolarını birleştirir

  2. Birleştirme noktası: orders.customer_id = customers.customer_id

  3. Her sipariş yanına müşteri adı ve soyadı eklenir

JOIN Koşulunun Önemi

JOIN koşulu (ON) olmadan veya yanlış yazılırsa kartezyen çarpım oluşur:

-- ⚠️ ON koşulu yok → her müşteri × her sipariş
SELECT c.first_name, o.order_id
FROM customers c, orders o;
-- 10 müşteri × 20 sipariş = 200 satır (çoğu anlamsız!)

-- ✅ ON koşulu ile → sadece eşleşen kayıtlar
SELECT c.first_name, o.order_id
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id;
-- Sadece anlamlı eşleşmeler

Eski Söz Dizimi vs Yeni (JOIN ... ON)

-- Eski söz dizimi (WHERE ile birleştirme — önerilmez)
SELECT c.first_name, o.order_id
FROM customers c, orders o
WHERE c.customer_id = o.customer_id;

-- Yeni söz dizimi (JOIN ... ON — önerilen)
SELECT c.first_name, o.order_id
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id;

İkisi aynı sonucu verir ama JOIN ... ON söz dizimi:

  • Daha okunabilir

  • Birleştirme koşulunu (ON) filtreleme koşulundan (WHERE) ayırır

  • LEFT/RIGHT JOIN destekler

💡 İpucu: Her zaman modern JOIN ... ON söz dizimini kullan. Eski virgüllü söz dizimi karmaşık sorgularda kafa karıştırır.

Gerçek Dünya Örneği — Sipariş Detayı

-- Bir siparişin tam detayı: müşteri + ürünler + fiyatlar
SELECT 
    o.order_id,
    CONCAT(c.first_name, ' ', c.last_name) AS musteri,
    c.city,
    o.order_date,
    p.product_name,
    oi.quantity AS adet,
    oi.unit_price AS birim_fiyat,
    oi.quantity * oi.unit_price AS satir_toplam,
    o.total_amount AS siparis_toplam,
    o.status
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id
INNER JOIN order_items oi ON o.order_id = oi.order_id
INNER JOIN products p ON oi.product_id = p.product_id
WHERE o.order_id = 1
ORDER BY p.product_name;

Bu sorgu 4 tabloyu birleştiriyor: orders → customers, orders → order_items → products. JOIN'in gücü burada ortaya çıkıyor — tek sorguda dağınık veriyi bir araya getiriyorsun.

Sıkça Yapılan Hatalar

  1. ON koşulunu unutmak: Kartezyen çarpım oluşur — milyonlarca satır döner.

  2. Yanlış sütunla birleştirmek: ON c.customer_id = o.order_id gibi yanlış eşleştirme saçma sonuçlar verir.

  3. Tablo alias'ı kullanmamak: Çoklu JOIN'de hangi sütunun hangi tabloya ait olduğu belirsizleşir.

  4. Ambiguous column hatası: İki tabloda aynı isimde sütun varsa (customer_id gibi) tablo adını/alias'ını belirtmelisin.

Özet

  • JOIN birden fazla tabloyu ortak sütunlar üzerinden birleştirir

  • INNER JOIN sadece eşleşen satırları, LEFT JOIN sol tablonun tamamını döndürür

  • ON koşulu birleştirme noktasını belirler — genellikle FK = PK

  • Tablo alias'ları (c, o, p) kodu kısaltır ve okunabilir kılar

  • Modern JOIN ... ON söz dizimini her zaman tercih et

  • ON koşulu olmadan JOIN kartezyen çarpım üretir — dikkat!

  • Birden fazla JOIN zincirleme kullanılabilir (3-4+ tablo)