INNER JOIN — Detaylı, Çoklu Tablo
Giriş — Sadece Eşleşenler
INNER JOIN, iki tabloda ortak koşulu sağlayan satırları birleştirir. Eşleşme olmayan satırlar sonuçta yer almaz. En sık kullanılan JOIN türüdür.
🎯 Analoji: İki okuldaki öğrenci listelerini düşün. INNER JOIN, her iki okulda da kayıtlı olan öğrencileri bulur. Sadece bir okulda olanlar sonuçta görünmez.
Temel INNER JOIN
-- Müşteriler ve siparişleri
SELECT c.first_name, c.last_name, o.order_id, o.total_amount, o.status
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id;Burada:
customerssol tablo,orderssağ tabloON c.customer_id = o.customer_idbirleştirme koşuluSipariş vermemiş müşteriler sonuçta YOKTUR
Müşterisi olmayan siparişler sonuçta YOKTUR (FK ile zaten imkansız)
INNER keyword'ü opsiyoneldir — JOIN tek başına INNER JOIN anlamına gelir:
-- İkisi de aynı:
SELECT c.first_name, o.order_id FROM customers c JOIN orders o ON c.customer_id = o.customer_id;
SELECT c.first_name, o.order_id FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id;Birden Fazla Tablo ile INNER JOIN
-- Sipariş detayı: müşteri + sipariş + ürünler
SELECT
c.first_name,
c.last_name,
o.order_id,
DATE_FORMAT(o.order_date, '%d.%m.%Y') AS order_date,
p.product_name,
oi.quantity,
CONCAT('₺', FORMAT(oi.unit_price, 2)) AS price,
CONCAT('₺', FORMAT(oi.quantity * oi.unit_price, 2)) AS line_total
FROM customers c
INNER JOIN orders o ON c.customer_id = o.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
ORDER BY o.order_id, p.product_name;Bu sorgu 4 tabloyu zincirleme birleştirir:
customers → orders → order_items → products
↑ ↑ ↑ ↑
customer_id order_id product_id product_idKategori Bilgisini de Ekleyelim
SELECT
c.first_name,
o.order_id,
cat.category_name,
p.product_name,
oi.quantity,
oi.unit_price
FROM customers c
INNER JOIN orders o ON c.customer_id = o.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
INNER JOIN categories cat ON p.category_id = cat.category_id
WHERE o.status = 'delivered'
ORDER BY o.order_date DESC;5 tablo birleştirildi — ve her JOIN bir öncekinin üzerine inşa ediliyor.
INNER JOIN ile Aggregate
-- Her müşterinin toplam sipariş tutarı
SELECT
c.customer_id,
CONCAT(c.first_name, ' ', c.last_name) AS customer_name,
COUNT(o.order_id) AS order_count,
ROUND(SUM(o.total_amount), 2) AS total_spent
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name
ORDER BY total_spent DESC;
-- Her kategorinin satış performansı
SELECT
cat.category_name,
COUNT(DISTINCT oi.order_id) AS order_count,
SUM(oi.quantity) AS units_sold,
ROUND(SUM(oi.quantity * oi.unit_price), 2) AS revenue
FROM categories cat
INNER JOIN products p ON cat.category_id = p.category_id
INNER JOIN order_items oi ON p.product_id = oi.product_id
GROUP BY cat.category_id, cat.category_name
ORDER BY revenue DESC;ON Koşulunda Ek Filtreler
-- Sadece teslim edilmiş siparişlerle JOIN
SELECT c.first_name, o.order_id, o.total_amount
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id AND o.status = 'delivered';
-- vs WHERE'de filtreleme (INNER JOIN'de sonuç aynı)
SELECT c.first_name, o.order_id, o.total_amount
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
WHERE o.status = 'delivered';💡 İpucu: INNER JOIN'de ek koşulu ON'a veya WHERE'e yazmak aynı sonucu verir. Ama LEFT JOIN'de fark yaratır — bunu bir sonraki derste göreceğiz.
USING Kısayolu
İki tablodaki birleştirme sütunu aynı isme sahipse USING kullanabilirsin:
-- ON yerine USING
SELECT c.first_name, o.order_id
FROM customers c
INNER JOIN orders o USING (customer_id);
-- = ON c.customer_id = o.customer_idGerçek Dünya Örneği — Sipariş Faturası
-- Fatura detayı
SELECT
CONCAT('FAT-', LPAD(o.order_id, 6, '0')) AS fatura_no,
DATE_FORMAT(o.order_date, '%d.%m.%Y %H:%i') AS tarih,
CONCAT(c.first_name, ' ', c.last_name) AS musteri,
c.email,
p.product_name AS urun,
oi.quantity AS adet,
CONCAT('₺', FORMAT(oi.unit_price, 2)) AS birim_fiyat,
CONCAT('₺', FORMAT(oi.quantity * oi.unit_price, 2)) AS satir_toplam
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 oi.item_id;Sıkça Yapılan Hatalar
Kartezyen çarpım: ON koşulu yanlış yazılırsa beklenenden çok fazla satır döner. Her JOIN'in doğru FK-PK eşleşmesi yaptığını kontrol et.
Performans: Her ek JOIN maliyettir. Gereksiz JOIN yapma — sadece ihtiyacın olan tabloları birleştir.
Ambiguous column: İki tabloda aynı isimli sütun varsa
c.customer_idgibi prefix kullan.
Özet
INNER JOIN sadece her iki tabloda da eşleşen satırları döndürür
JOIN=INNER JOIN(INNER opsiyonel)Birden fazla INNER JOIN zincirleme kullanılabilir (3, 4, 5+ tablo)
USING, sütun adları aynı olduğunda kısa yol sağlar
ON'daki ek koşullar INNER JOIN'de WHERE ile aynı sonucu verir
Her JOIN doğru FK-PK eşleşmesi kullanmalı
AI Asistan
Sorularını yanıtlamaya hazır