6 dk

Bilmeniz Gereken 6 SQL JOIN (Basit, Açık Örneklerle)

INNER, LEFT, RIGHT, FULL OUTER, CROSS ve SELF dahil olmak üzere her analistin bilmesi gereken 6 SQL JOIN'i pratik örnekler ve yaygın tuzaklarla öğrenin.

Bilmeniz Gereken 6 SQL JOIN (Basit, Açık Örneklerle)

SQL JOIN Nedir ve Neden Kullanırsınız?

Bir SQL JOIN, iki (veya daha fazla) tablonun ilişkili bir sütun üzerinde—genellikle bir ID—eşleşen satırlarını tek bir sonuçta birleştirmenizi sağlar.

JOIN'lerin önemi

Gerçek dünya veritabanları çoğunlukla aynı bilgiyi tekrar etmemek için ayrı tablolara bölünür. Örneğin bir müşterinin adı customers tablosunda, satın alımları ise orders tablosunda saklanır. JOIN'ler, bu parçaları gerektiğinde yeniden bir araya getirmenin yoludur.

Bu nedenle JOIN'ler raporlama ve analizde her yerde karşımıza çıkar:

  • Müşteri adlarını, sipariş toplamlarını ve ödeme durumunu içeren bir satış raporu oluşturmak
  • Henüz sipariş vermemiş müşterileri bulmak
  • Ödemesi olmayan siparişler gibi uyuşmazlıkları denetlemek
  • Birden çok ilgili satırdan "müşteri başına bir satır" özetleri oluşturmak

JOIN'ler olmasa ayrı sorgular çalıştırıp sonuçları elle birleştirmeniz gerekecekti—yavaş, hata yapmaya açık ve tekrarlanması zor.

Eğer ilişkisel bir veritabanı üzerinde ürünler (paneller, yönetici ekranları, dahili araçlar, müşteri portalları) geliştiriyorsanız, JOIN'ler ham tabloları kullanıcıya gösterilen görünümlere dönüştürür. Koder.ai gibi platformlar (React + Go + PostgreSQL uygulamaları sohbetten üretenler) bile doğru liste sayfaları, raporlar ve mutabakat ekranları gerektiğinde sağlam JOIN mantığına dayanır—çünkü veritabanı mantığı hızlansa da ortadan kaybolmaz.

En çok kullandığınız 6 JOIN türü

Bu rehber, günlük SQL işlerinin çoğunu kapsayan altı JOIN türüne odaklanır:

  • INNER JOIN: Her iki tabloda da eşleşen satırları döndürür ("doğrulanmış ilişkileri göster" için uygun).
  • LEFT JOIN: Sol tablodaki tüm satırları tutar, sağdan varsa eşleşmeleri ekler ("ilgili veri eksikse bile sol tarafı dahil et" için uygun).
  • RIGHT JOIN: LEFT JOIN'in aynasıdır (daha az yaygın, ama sorgu stili veya okunabilirlik açısından faydalı olabilir).
  • FULL OUTER JOIN: Her iki tablodan da tüm satırları tutar, mümkünse eşleştirir (mutabakat ve eksik eşleme bulmada mükemmel).
  • CROSS JOIN: Tüm satır kombinasyonlarını üretir (takvimler, senaryolar veya test verisi oluşturmak için kullanışlı—aynı zamanda yanlış kullanmaya çok müsait).
  • SELF JOIN: Bir tabloyu kendisiyle birleştirme (çalışan/yönetici gibi hiyerarşiler için elverişli).

Kısa bir sözdizimi notu

JOIN sözdizimi çoğu SQL veritabanında (PostgreSQL, MySQL, SQL Server, SQLite) çok benzerdir. Bazı farklılıklar vardır—özellikle FULL OUTER JOIN desteği ve bazı uç durum davranışlarında—ama kavramlar ve temel kalıplar kolayca aktarılır.

Örnek Tablolarımız (Customers, Orders, Payments)

JOIN örneklerini basit tutmak için üç küçük tablo kullanacağız: müşteriler sipariş verir ve siparişlerin ödemesi olabilir (veya olmayabilir).

Küçük bir not: örnek tablolar aşağıda sadece birkaç sütunu gösteriyor ama sonraki sorgularda order_date, created_at, status veya paid_at gibi tipik alanlara referans verilecektir. Bu sütunları üretim şemalarında sık bulunan tipik alanlar olarak düşünün.

1) customers

Birincil anahtar: customer_id

customer_idname
1Ava
2Ben
3Chen
4Dia

2) orders

Birincil anahtar: order_id
Yabancı anahtar: customer_idcustomers.customer_id

order_idcustomer_idorder_total
101150
1021120
103235
104570

Dikkat edin: order_id = 104, customer_id = 5 referans ediyor; bu customers içinde yok. Bu "eşleşmeyen" örnek, LEFT JOIN, RIGHT JOIN ve FULL OUTER JOIN davranışlarını görmek için faydalıdır.

3) payments

Birincil anahtar: payment_id
Yabancı anahtar: order_idorders.order_id

payment_idorder_idamount
900110150
900210260
900310260
900499925

İki önemli öğretici detay:

  • order_id = 102 iki ödeme satırına sahip (bölünmüş ödeme). orders ile payments birleştirildiğinde o sipariş iki kez görünecektir—işte burada çoğaltmalar insanları şaşırtır.
  • payment_id = 9004, order_id = 999 referans ediyor; bu orders içinde yok. Bu da başka bir "eşleşmeyen" durum oluşturur.

Bu tabloları JOIN ettiğimizde ne beklemeli

  • Eşleşen satırlar: örn. müşteri 1 ↔ sipariş 101/102; sipariş 101 ↔ ödeme 9001.
  • Eşleşmeyen satırlar: örn. müşteri 3 ve 4'ün siparişi yok; sipariş 104'ün müşterisi yok; ödeme 9004'ün siparişi yok.
  • Çoğaltmalar: orders ile payments birleştirildiğinde 102 numaralı sipariş iki kez tekrarlanır.

INNER JOIN: Sadece Eşleşenleri Tut

INNER JOIN, yalnızca her iki tabloda da eşleşme olan satırları döndürür. Bir müşterinin siparişi yoksa sonuçta görünmez. Bir sipariş var ama referans verdiği müşteri yoksa (kötü veri), o sipariş de görünmez.

Temel kalıp

Bir "sol" tablo seçersiniz, bir "sağ" tabloyu birleştirirsiniz ve ON koşulunda nasıl ilişkilendirileceğini söylersiniz.

SELECT
  c.customer_id,
  c.name,
  o.order_id,
  o.order_date
FROM customers c
INNER JOIN orders o
  ON o.customer_id = c.customer_id;

Ana fikir ON o.customer_id = c.customer_id satırıdır: SQL'e satırların nasıl eşleşeceğini söyler.

Gerçek kullanım: sipariş veren müşteriler

Sadece en az bir sipariş vermiş müşterileri (ve sipariş detaylarını) listelemek istiyorsanız, INNER JOIN doğal seçimdir:

SELECT
  c.name,
  o.order_id,
  o.total_amount
FROM customers c
INNER JOIN orders o
  ON o.customer_id = c.customer_id
ORDER BY o.order_id;

Bu, "sipariş takip e-postası gönder" veya "satış başına müşteri geliri hesapla" gibi kullanım durumları için uygundur (sadece satın alma yapan müşterilerle ilgileniyorsanız).

Yaygın hata: eksik veya belirsiz join koşulları

Join yazıp ON koşulunu unutursanız (veya yanlış sütunla eşleştirirseniz), istemeden Kartezyen çarpımı (her müşteri ile her sipariş) oluşturabilir veya incelikli şekilde yanlış eşlemeler üretebilirsiniz.

Kötü (bunu yapmayın):

SELECT c.name, o.order_id
FROM customers c
JOIN orders o;

Her zaman ON (veya özel durumlarda USING) ile net bir join koşulu yazdığınızdan emin olun.

LEFT JOIN: Sol Tablodaki Her Şeyi Tut

LEFT JOIN, sol tablodaki tüm satırları döndürür ve sağ tablodan eşleşenleri ekler; eşleşme yoksa sağ taraf sütunları NULL olur.

Ne zaman kullanılır

Ana tablodan eksiksiz bir liste istiyorsanız ve ilişkili veriler opsiyonelse LEFT JOIN kullanın.

Örnek: "Tüm müşterileri gösterin ve varsa siparişlerini ekleyin."

SELECT
  c.customer_id,
  c.name,
  o.order_id,
  o.order_date
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id
ORDER BY c.customer_id;
  • Siparişi olan müşteriler sipariş detaylarıyla görünür.
  • Siparişi olmayan müşteriler yine görünür, ancak o.order_id gibi orders sütunları NULL olur.

"Eşleşmeyenleri" bulma (klasik kalıp)

Çok yaygın bir kullanım, ilgili kaydı olmayan öğeleri bulmaktır.

Örnek: "Hiç sipariş vermemiş müşteriler kimler?"

SELECT
  c.customer_id,
  c.name
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id
WHERE o.order_id IS NULL;

WHERE ... IS NULL koşulu, join eşleşmesi bulunamayan sol-tablo satırlarını tutar.

Dikkat: birden fazla eşleşme satırları çoğaltır

LEFT JOIN, sağ tarafta birden çok eşleşme olduğunda sol tablo satırlarını "çoğaltabilir".

Bir müşterinin 3 siparişi varsa, o müşteri 3 kez görünür—her sipariş için bir satır. Bu beklenen bir davranıştır ama müşteri saymak gibi durumlarda şaşırtıcı olabilir.

Örneğin, bu sorgu siparişleri sayar (müşterileri değil):

SELECT COUNT(*)
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id;

Müşteri saymak istiyorsanız genellikle anahtarın sayısını sayarsınız (ör. COUNT(DISTINCT c.customer_id)), ölçtüğünüz şeye bağlı olarak.

RIGHT JOIN: Sağ Tablodaki Her Şeyi Tut

RIGHT JOIN, sağ tablodaki tüm satırları tutar ve sadece eşleşen sol tablodaki satırları ekler. Eşleşme yoksa sol tablonun sütunları NULL olur. Aslında LEFT JOIN'in tersidir.

Basit örnek

Örnek tablolarımızı kullanarak, her ödemeyi listelemek isteyebileceğinizi düşünün; ödeme bir siparişe bağlanamıyor olabilir (sipariş silinmiş olabilir veya ödeme verisi karışıksa).

SELECT
  o.order_id,
  o.customer_id,
  p.payment_id,
  p.amount,
  p.paid_at
FROM orders o
RIGHT JOIN payments p
  ON o.order_id = p.order_id;

Sonuç:

  • Tüm ödemeler dahil edilir (çünkü payments sağ tarafta).
  • Bir ödemenin eşleşen siparişi yoksa o.order_id ve o.customer_id NULL olur.

Aynı sorguyu LEFT JOIN ile yazmak (çoğunlukla tercih edilir)

Çoğu zaman RIGHT JOIN, tablo sırasını değiştirip LEFT JOIN ile yeniden yazılabilir:

SELECT
  o.order_id,
  o.customer_id,
  p.payment_id,
  p.amount,
  p.paid_at
FROM payments p
LEFT JOIN orders o
  ON o.order_id = p.order_id;

Aynı sonucu döndürür; ancak birçok kişi için okunması daha kolaydır: önce ilgilendiğiniz "ana" tabloyu (burada payments) başlatırsınız ve sonra isteğe bağlı veriyi çekersiniz.

Okunabilirlik: neden birçok ekip RIGHT JOIN'den kaçınır

Çoğu SQL stil kılavuzu RIGHT JOIN kullanımını tavsiye etmez çünkü okuyan kişinin mantığı tersine çevirmesini gerektirir. Bir standart haline getirilen yaklaşım:

  • "Ana tabloyla başla"
  • "Ek tabloları LEFT JOIN ile ekle"

Opsiyonel ilişkiler her zaman LEFT JOIN ile yazıldığında sorgular taraması daha kolay olur.

RIGHT JOIN hâlâ kullanışlı olabilir

Uzun bir sorguyu düzenlerken, "tutulması gereken" tablo sağda ise tüm sorguyu tersine çevirmek yerine tek bir join'i RIGHT JOIN yapmak hızlı ve düşük riskli bir değişiklik olabilir.

FULL OUTER JOIN: Her İki Tablodaki Tüm Satırları Tut

SQL'inizi üretime alın
Deneyleri yavaşlatmadan uygulamanızı dağıtın ve barındırın.

FULL OUTER JOIN, her iki tablodaki tüm satırları döndürür.

  • Eğer satır eşleşiyorsa tek birleşik satır alırsınız (INNER JOIN gibi).
  • Sadece sol tabloda olan satırlar, sağ sütunlar NULL olacak şekilde yine görünür.
  • Sadece sağ tabloda olan satırlar, sol sütunlar NULL olacak şekilde görünür.

Ne zaman işe yarar

Klasik bir kullanım, siparişler vs ödemeler mutabakatıdır:

  • Ödemeli siparişleri görmek (eşleşenler)
  • Ödemesiz siparişleri görmek (solda olanlar)
  • Yalnızca ödeme olan, siparişi olmayan durumları görmek (sağda olanlar)

Örnek:

SELECT
  o.order_id,
  o.customer_id,
  p.payment_id,
  p.amount
FROM orders o
FULL OUTER JOIN payments p
  ON p.order_id = o.order_id;

Veritabanı desteği

FULL OUTER JOIN, PostgreSQL, SQL Server ve Oracle tarafından desteklenir.

MySQL ve SQLite'ta doğrudan yoktur; bir çözüm gerekir.

Taşınabilir alternatif: LEFT JOIN ve RIGHT JOIN'i UNION ile birleştirmek

Veritabanınız FULL OUTER JOIN desteklemiyorsa, bunu şu şekilde taklit edebilirsiniz:

  1. orders tablosunun tüm satırlarını (mevcutsa eşleşen ödemelerle) alın,
  2. payments tablosunda eşleşmeyen satırları ekleyin.

Yaygın bir kalıp:

SELECT o.order_id, o.customer_id, p.payment_id, p.amount
FROM orders o
LEFT JOIN payments p
  ON p.order_id = o.order_id

UNION

SELECT o.order_id, o.customer_id, p.payment_id, p.amount
FROM orders o
RIGHT JOIN payments p
  ON p.order_id = o.order_id;

İpucu: bir tarafta NULL gördüğünüzde, o satırın diğer tabloda eksik olduğunu anlarsınız—mutabakat ve denetimler için tam aradığınız şey budur.

CROSS JOIN: Tüm Kombinasyonları Yap (Dikkatli Kullan)

CROSS JOIN, iki tablonun her olası eşleşmesini döndürür. Tablo A 3 satır, tablo B 4 satırsa sonuç 3 × 4 = 12 satır olur. Buna Kartezyen çarpım denir.

Kulağa korkutucu geliyor—ve olabilir—ama kombinasyon üretmek istediğinizde gerçekten faydalıdır.

Küçük, güvenli bir örnek: beden × renk (SKU oluşturma)

Ürün seçeneklerini ayrı tablolarda tuttuğunuzu düşünün:

  • sizes: S, M, L
  • colors: Red, Blue

CROSS JOIN tüm varyantları üretmek için kullanılabilir:

SELECT
  s.size,
  c.color
FROM sizes AS s
CROSS JOIN colors AS c;

Sonuç (3 × 2 = 6 satır):

  • S / Red
  • S / Blue
  • M / Red
  • M / Blue
  • L / Red
  • L / Blue

Büyük uyarı: sonuçlar hızla büyür

Satır sayıları çarpıldığından CROSS JOIN hızla patlayabilir:

  • 10.000 müşteri × 50 ürün = 500.000 satır
  • 100.000 × 100.000 = 10.000.000.000 satır

Bu sorguları yavaşlatabilir, belleği zorlayabilir ve kimsenin kullanamayacağı bir çıktı üretebilir. Kombinasyonlara ihtiyacınız varsa, giriş tablolarını küçük tutun veya kontrollü filtreler ekleyin.

SELF JOIN: Bir Tabloyu Kendisiyle Birleştirmek

Bir raporlama panosu oluşturun
Tablolarınızı sohbetle liste sayfalarına, filtrelere ve raporlara dönüştürün.

SELF JOIN, adından da anlaşılacağı gibi bir tabloyu kendisiyle birleştirmektir. Bir satırın aynı tablodaki başka bir satırla ilişkili olduğu durumlarda faydalıdır—en yaygın örnek çalışanlar ve yöneticiler hiyerarşisidir.

Neden takma adlara ihtiyacınız var (ve nasıl yardımcı olur)

Aynı tabloyu iki kez kullandığınız için her "kopyaya" farklı bir alias vermelisiniz. Alias'lar sorguyu okunur kılar ve SQL'e hangi tarafı kastettiğinizi söyler.

Yaygın bir kalıp:

  • e çalışan için
  • m yönetici için

Pratik örnek: çalışanlar ve yöneticileri

employees tablosu şu kolonlara sahip olsun:

  • id
  • name
  • manager_id (başka bir çalışanın id'sine işaret eder)

Her çalışanı yönetici adıyla listelemek için:

SELECT
  e.id,
  e.name AS employee_name,
  m.name AS manager_name
FROM employees e
LEFT JOIN employees m
  ON e.manager_id = m.id;

Üst düzey yöneticileri (NULL manager_id) ele alma

Sorgu LEFT JOIN kullanır, INNER JOIN değil. Çünkü bazı çalışanların (ör. CEO) yöneticisi olmayabilir; bu durumda manager_id genellikle NULL olur ve LEFT JOIN çalışan satırını tutup manager_name'i NULL gösterir.

INNER JOIN kullansaydınız, üst düzey yöneticiler sonuçtan kaybolurdu çünkü eşleşecek bir yönetici satırı yoktur.

Join Koşulları: ON vs USING (Neden Önemli)

Bir JOIN, iki tablonun nasıl ilişkilendiğini bilmez—bunu siz belirtmelisiniz. Bu ilişki join koşulunda tanımlanır ve JOIN'in yanında yer almalıdır çünkü bu, tabloların nasıl eşleştiğini açıklar, nihai filtreleme değil.

ON: en esnek ve en yaygın olan

Farklı sütun isimleri, birden çok koşul veya ek kurallar gerektiğinde ON kullanın.

SELECT
  c.customer_id,
  c.name,
  o.order_id,
  o.created_at
FROM customers AS c
INNER JOIN orders AS o
  ON o.customer_id = c.customer_id;

ON ile iki sütunda eşleştirme veya daha karmaşık mantık tanımlayabilirsiniz.

USING: sadece aynı isimli sütunlar için kısa yol

Bazı veritabanları (PostgreSQL, MySQL) USING desteği sunar. Her iki tabloda aynı ada sahip bir sütun varsa ve sadece bu sütunla eşlemek istiyorsanız kısaltma sağlar.

SELECT
  customer_id,
  name,
  order_id
FROM customers
JOIN orders
USING (customer_id);

USING genelde çıktıdan tek bir customer_id sütunu döndürme avantajı sağlar (iki kopya yerine).

Belirsiz sütun isimlerinden kaçının: joinlerde her zaman nitelendirin

Join sonrası sütun isimleri çakışabilir (id, created_at, status). SELECT id yazarsanız veritabanı "ambiguous column" hatası verebilir—ya da yanlış id'yi okuyabilirsiniz.

Açıklık için tablo önekleri veya alias kullanın:

SELECT c.customer_id, o.order_id
FROM customers AS c
JOIN orders AS o
  ON o.customer_id = c.customer_id;

JOIN ile SELECT * kullanmaktan kaçının

SELECT * joinlerle hızla karmaşıklaşır: gereksiz sütunları çekersiniz, isim çakışmaları olur ve sorgunun amacı zor anlaşılır. Bunun yerine ihtiyacınız olan sütunları seçin—sonuç daha temiz, bakımı daha kolay ve genelde daha verimlidir.

Birleşik Veriyi Filtreleme: WHERE vs ON

JOIN yaparken, WHERE ve ON her ikisi de "filtre" uygular ama farklı zamanlarda.

  • ON: eşleşmenin hangi satırlarla yapılacağını belirler.
  • WHERE: birleşim oluşturulduktan sonra nihai sonucu filtreler.

Bu zamanlama farkı, insanların LEFT JOIN'i yanlışlıkla INNER JOIN gibi davranır hale getirmesine neden olur.

WHERE, LEFT JOIN'i nasıl bozabilir

Tüm müşterileri, hatta yakın zamanda ödenmiş siparişi olmayanları istiyorsunuz diyelim.

SELECT c.customer_id, c.name, o.order_id, o.status, o.order_date
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id
WHERE o.status = 'PAID'
  AND o.order_date >= DATE '2025-01-01';

Sorun: siparişi olmayan müşteriler için o.status ve o.order_date NULL olur. WHERE koşulu bu satırları eler; böylece LEFT JOIN etkide INNER JOIN gibi davranır.

JOIN ile ilgili koşulları ON içine taşıyarak eşleşmeyenleri saklayın

SELECT c.customer_id, c.name, o.order_id, o.status, o.order_date
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.customer_id
 AND o.status = 'PAID'
 AND o.order_date >= DATE '2025-01-01';

Böylece nitelikli siparişi olmayan müşteriler yine görünür (sipariş sütunları NULL olur), ki genelde LEFT JOIN kullanmanın amacı budur.

Hızlı kontrol listesi: ON ve WHERE'a ne koymalı?

  • ON: sağ tablodan hangi satırların eşleşebileceğini tanımlar (status/tarih/type gibi sağ-tablo filtreleri).
  • WHERE: nihai olarak hangi satırları tutmak istediğinizi tanımlar (sol tablo filtreleri veya gerçekten eşleşme gerektiren durumlar).
  • "Tüm sol satırları tut ama sağ satırları kısıtla" istiyorsanız, LEFT JOIN + ON içindeki koşullar tercih edin.
  • Gerçekten "sadece eşleşenleri" istiyorsanız, INNER JOIN (veya açıkça WHERE o.order_id IS NOT NULL) kullanın.

Çoğaltılmış Satırlardan ve Çoğa-Çoğa Tuzaklarından Kaçınma

Korkmadan dene
Rapor bozulursa değişiklikleri güvenle denemek ve geri almak için deney yapın.

Joinler sadece sütun eklemez—satırları da çoğaltabilir. Bu genelde doğru davranıştır ama toplamlar aniden iki katına çıkınca sürpriz yaratabilir.

Neden satırlar çoğalır

Bir join, her eşleşen satır çifti için bir çıktı satırı üretir.

  • Birden-çoğa: Bir müşterinin birçok siparişi olabilir; customersı orders ile birleştirirseniz her müşteri sipariş başına birden fazla kez görünebilir.
  • Çoğa-çoğa: Eğer bir siparişin birden fazla ödemesi ve bir de order_items gibi başka bir "çok" tablonuz varsa, payments × items etkisiyle beklenmedik çarpımlar oluşur.

Join öncesi grupla (pre-aggregate)

Eğer hedefiniz "müşteri başına bir satır" veya "sipariş başına bir satır" ise, "çok" tarafı önce özetleyin, sonra join yapın.

-- Ödemelerden sipariş başına bir satır
WITH payment_totals AS (
  SELECT
    order_id,
    SUM(amount) AS total_paid,
    COUNT(*)   AS payment_count
  FROM payments
  GROUP BY order_id
)
SELECT
  o.order_id,
  o.customer_id,
  COALESCE(pt.total_paid, 0) AS total_paid,
  COALESCE(pt.payment_count, 0) AS payment_count
FROM orders o
LEFT JOIN payment_totals pt
  ON pt.order_id = o.order_id;

Bu, join şeklinin tahmin edilebilir olmasını sağlar: bir sipariş satırı bir sipariş satırı olarak kalır.

DISTINCT son çare olsun

SELECT DISTINCT, çoğaltmaları görünürde düzeltir ama gerçek problemi gizleyebilir:

  • Meşru satırları sessizce düşürebilir.
  • Eksik veya yanlış join koşullarını örtebilir.
  • Toplamları bozabilir (özellikle SUM ve COUNT ile).

Sadece çoğaltmaların tamamen kazara olduğunu ve nedenini bildiğinizde kullanın.

Hızlı güvenlik kontrolü: sayıları doğrulayın

Sonuca güvenmeden önce satır sayılarınızı karşılaştırın:

  • Ana tablodaki satır sayısını sayın (örn. orders).
  • Join sonrası satır sayısını sayın.
  • Sayı beklenmedik şekilde artıyorsa hangi anahtarların çoklu eşleşmeye neden olduğunu inceleyin ve gerekiyorsa pre-aggregate veya farklı bir join yolu seçin.

Performans Temelleri ve Hızlı JOIN Püf Noktası

JOIN'ler genelde "yavaş sorguların" suçlusu ilan edilir ama gerçek sebep çoğunlukla veritabanına ne kadar veri birleştirmesini istediğiniz ve eşleşen satırları ne kadar hızlı bulabildiği ile ilgilidir.

İndeksleme (kavramsal) ve JOIN'lere nasıl yardımcı olur

Bir indeksi kitap içindeki içindekiler tablosu gibi düşünün. İndeks yoksa veritabanı JOIN koşulunu sağlamak için çok sayıda satırı taramak zorunda kalabilir. JOIN anahtarında (ör. customers.customer_id ve orders.customer_id) indeks varsa veritabanı ilgili satırlara çok daha hızlı atlayabilir.

Nasıl kullanacağınızı bilmek için iç detaylara hakim olmanız gerekmez: eğer bir sütun sık sık eşleşme için kullanılıyorsa indekse uygun bir adaydır.

Stabil anahtarlar üzerinde JOIN yapın (isimler veya e-postalar değil)

Mümkün olduğunda, kararlı, tekil tanımlayıcılar üzerinde join yapın:

  • İyi: customers.customer_id = orders.customer_id
  • Riskli: customers.email = orders.email veya customers.name = orders.name

İsimler değişebilir ve tekrar edebilir. E-postalar değişebilir, eksik olabilir veya format/farklılık sorunları olabilir. ID'ler tutarlı eşleme için tasarlanmıştır ve genelde indekslidir.

İş miktarını erken azaltın

İki alışkanlık JOIN'leri belirgin şekilde hızlandırır:

  1. Daha az sütun seçin. Birden çok tabloya join yaparken SELECT *'den kaçının—gereksiz sütunlar bellek ve ağ kullanımını artırır.
  2. Satırları JOIN'den önce veya JOIN sırasında sınırlandırın. Filtrelemeyi mümkün olduğunca erkene alın.

Örnek: önce siparişleri sınırlayıp sonra join yapın:

SELECT c.customer_id, c.name, o.order_id, o.created_at
FROM customers c
JOIN (
  SELECT order_id, customer_id, created_at
  FROM orders
  WHERE created_at >= DATE '2025-01-01'
) o
  ON o.customer_id = c.customer_id;

Eğer bu sorgularla bir uygulama oluşturuyorsanız (ör. PostgreSQL destekli bir raporlama sayfası), Koder.ai gibi araçlar şemayı, uç noktaları ve UI'ı hızla oluşturmanıza yardımcı olabilir—ama doğruyu belirleyen JOIN mantığını siz kontrol etmelisiniz.

Hızlı JOIN başvuru tablosu

  • INNER JOIN → her iki tabloda da eşleşenler
  • LEFT JOIN → sol tablodan tüm satırlar, sağdan eşleşmeler (eşleşmeyenler NULL)
  • RIGHT JOIN → sağ tablodan tüm satırlar, soldan eşleşmeler (NULL ile)
  • FULL OUTER JOIN → her iki tablodan tüm satırlar; eşleşenler birleşir, eşleşmeyenler NULL
  • CROSS JOIN → satırların tüm kombinasyonları (boyut çarpılır; dikkatli kullan)
  • SELF JOIN → tablonun kendisiyle birleştirilmesi (hiyerarşiler ve karşılaştırmalar için)

SSS

SQL JOIN nedir, basitçe anlatır mısınız?

Bir SQL JOIN, iki (veya daha fazla) tablonun ilişkili sütunları üzerinden eşleşen satırlarını tek bir sonuç kümesinde birleştirir—çoğunlukla birincil anahtar ile yabancı anahtar arasındaki eşleme (customers.customer_id = orders.customer_id gibi). Normalleştirilmiş tabloları raporlar, denetimler veya analizler için yeniden bağlamanın yoludur.

INNER JOIN ne zaman kullanmalıyım?

Sadece her iki tabloda da ilişki bulunan satırları istediğinizde INNER JOIN kullanın.

  • Sipariş vermemiş müşteriler sonuçta görünmez.
  • Eksik müşteri referansı olan siparişler görünmez.

Onaylanmış ilişkileri göstermek için idealdir; örneğin sadece gerçekten sipariş veren müşterileri listelemek gibi.

Diğer tabloda eşleşmesi olmayan satırları nasıl bulurum?

LEFT JOIN ana (sol) tablodan tüm satırları alır ve sağ tablodan eşleşenleri ekler.

“Eşleşmesi olmayan” kayıtları bulmak için şu yaygın kalıbı kullanın:

SELECT c.customer_id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.order_id IS NULL;

Bu, hiç sipariş vermemiş müşterileri bulur.

RIGHT JOIN'e gerçekten ihtiyacım var mı, nasıl LEFT JOIN ile değiştiririm?

RIGHT JOIN, sağ tablodaki tüm satırları tutar ve sol tablodan sadece eşleşenleri ekler. Birçok ekip bunu geriye doğru okunduğu için tercih etmez.

Çoğu durumda, tablo sırasını değiştirip LEFT JOIN kullanarak aynı sonucu elde edebilirsiniz:

FROM payments p
LEFT JOIN orders o ON o.order_id = p.order_id
FULL OUTER JOIN en çok ne için kullanılır?

FULL OUTER JOIN, hem sol hem sağ tablodaki tüm satırları döndürmek için kullanılır: eşleşenler birleşir, tek tarafta olanlar diğer sütunlarda NULL gösterir.

Mutabakatlar için idealdir: "ödeme olan siparişler", "ödemesiz siparişler" ve "siparişi olmayan ödemeler" gibi tüm durumlardan aynı anda haberdar olmak istediğinizde kullanırsınız.

Veritabanım FULL OUTER JOIN desteklemiyorsa ne yapmalıyım?

Bazı veritabanları (özellikle MySQL ve SQLite) FULL OUTER JOIN'i doğrudan desteklemez. Yaygın bir çözüm, iki sorguyu birleştirmektir:

  • orders LEFT JOIN payments
  • ve sadece ödemeler tarafında olan satırları ekleyen bir diğer sorgu

Genelde bu UNION ile yapılır (veya dikkatle UNION ALL).

CROSS JOIN nedir ve ne zaman işe yarar?

CROSS JOIN, iki tablo arasındaki tüm kombinasyonları döndürür (Kartezyen çarpım). Senaryolar oluşturmak (ör. beden × renk) veya test verisi üretmek için kullanışlıdır.

Dikkat: satır sayısı hızla çarpılır; girdiler küçük ve kontrollü değilse çıktı patlayabilir.

SELF JOIN nedir ve neden takma adlar (alias) kullanmalıyım?

Self join, bir tablonun kendisiyle ilişkilendirildiği durumdur; genellikle çalışan → yönetici gibi hiyerarşiler için kullanılır.

Aynı tabloyu iki kez kullandığınız için her kopyaya farklı takma ad (alias) vermeniz gerekir:

FROM employees e
LEFT JOIN employees m
  ON e.manager_id = m.id
JOIN'lerde ON ile WHERE arasındaki fark nedir?

ON, tabloların nasıl eşleşeceğini tanımlar; WHERE ise birleşim sonrası nihai sonucu filtreler. LEFT JOIN ile sağ tabloya ait bir koşulu WHERE içine koymak, NULL eşleşmeleri eler ve etkide INNER JOIN gibi davranır.

Eğer sol tablodaki tüm satırları tutmak ama sağ tablodan sadece belirli satırların eşleşmesini istiyorsanız, sağ-tablo koşullarını ON içine koyun.

Joinler neden çoğaltma yapar ve çifte sayımı nasıl önlerim?

Joinler, birden-çoğa veya çoğa-çoğa ilişkilerde satırları çoğaltabilir. Örneğin, bir siparişin iki ödemesi varsa orders ile payments birleştirildiğinde o sipariş iki kez görünür.

"Satır başına bir" sonuç istiyorsanız, çoklu tarafı önce gruplayıp topladıktan (SUM, COUNT) sonra join yapın. DISTINCT son çare olmalı; gerçek problemi gizleyebilir ve toplamları bozabilir.

Related posts