İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

SQL JOIN Sonucu Neden Satır Sayısı Artar? Örneklerle Teşhis

sql-join-sonucu-neden-satir-sayisi-artar
Bu yazıda neler var?
  1. JOIN neden bir öğrenciyi birden fazla satıra çevirir?
  2. Satır sayısı arttığında nasıl teşhis edersin? Üç adımlı çerçeve
  3. INNER JOIN ve LEFT JOIN satır sayısını nasıl etkiler?
  4. Eksik JOIN koşulu ve yanlış sütunla eşleştirme neden ayrı birer hatadır?
  5. DISTINCT neden sorunu çözmez, yalnızca gizler?
  6. JOIN sonucunu doğrulamak için kısa kontrol listesi

SQL JOIN sonucunda satır sayısı artıyorsa, karşı tabloda aynı anahtara sahip birden fazla kayıt var demektir. JOIN satırları kendiliğinden çoğaltmaz; eşleşme koşulu bir satırın karşı tarafta birden fazla kayıtla eşleşmesine izin veriyorsa sonuç kümesi büyür. Bu yazıda küçük bir örnekle artışın nereden geldiğini görecek, ardından sebebi bulmak için üç adımlı bir teşhis yöntemi uygulayacaksın.

JOIN neden bir öğrenciyi birden fazla satıra çevirir?

JOIN, koşulu sağlayan her eşleşmeyi sonuca ayrı bir satır olarak yazar. İki tabloyu ogrenci_id üzerinden bağladığında soldaki bir satırın sağda kaç eşi varsa o kadar satır üretilir.

Burada iki rol var. ogrenciler.ogrenci_id birincil anahtardır (primary key): her öğrenciyi tek başına tanımlar ve tekrar etmez. kayitlar.ogrenci_id ise yabancı anahtardır (foreign key): kaydın hangi öğrenciye ait olduğunu gösterir ve aynı değer birçok satırda bulunabilir. Bu düzene birden çoğa ilişki denir: bir öğrencinin birçok kaydı olabilir, bir kayıt tek öğrenciye aittir.

Başlangıç durumu: her öğrencinin en fazla bir kaydı var

ogrenciler tablosunda dört öğrenci var: Ayşe (1), Can (2), Elif (3) ve Deniz (4). kayitlar tablosunda ise üç kayıt var: Ayşe-Matematik, Can-Fizik, Elif-Kimya. Deniz'in kaydı yok.

SELECT o.ad, k.ders
FROM ogrenciler o
INNER JOIN kayitlar k ON o.ogrenci_id = k.ogrenci_id;

Beklenen çıktı 3 satırdır; Deniz eşleşmediği için INNER JOIN sonucunda yer almaz:

adders
AyşeMatematik
CanFizik
ElifKimya

Can ikinci bir derse kaydolunca ne olur?

Can'a ikinci bir ders kaydı ekle:

INSERT INTO kayitlar (ogrenci_id, ders) VALUES (2, 'Biyoloji');

Aynı JOIN sorgusunu yeniden çalıştırdığında sonuç 4 satıra çıkar. Satırların sırası ORDER BY kullanmadığın sürece değişebilir, önemli olan Can'ın iki kez görünmesidir:

adders
AyşeMatematik
CanFizik
CanBiyoloji
ElifKimya

Sorgu hata vermedi ve JOIN doğru çalıştı. Can gerçekten iki derse kayıtlı olduğu için iki satır görmen gerekir; artış ilişkinin doğasından gelir. Sorun, bu artışı beklemeden sorguyu yazdığında ortaya çıkar. Örneğin öğrenci başına tek satır isteyen bir rapor bu sonuçla yanlış olur.

Satır sayısı arttığında nasıl teşhis edersin? Üç adımlı çerçeve

Satır sayısı arttığında nasıl teşhis edersin? Üç adımlı çerçeve

Sonuç beklediğinden büyükse tahmin yürütmek yerine sırayla şu üç adımı uygula:

  1. İlişki türünü belirle. İki tablo arasındaki bağ bire bir mi, birden çoğa mı, çoktan çoğa mı? Sorguyu çalıştırmadan önce beklenen satır sayısını tahmin et. Birden çoğa ilişkide sonuç, çoklu taraftaki eşleşen kayıt sayısı kadar satır içerir. Bizim örnekte 4 kayıt olduğundan 4 satır beklemen gerekir.
  2. Anahtarın benzersizliğini COUNT ile kontrol et. Hangi anahtarın tekrar ettiğini şu sorgu gösterir:
    SELECT ogrenci_id, COUNT(*) AS kayit_sayisi
    FROM kayitlar
    GROUP BY ogrenci_id
    HAVING COUNT(*) > 1;
    Beklenen çıktı yalnızca Can'ı (ogrenci_id 2) gösterir:
    ogrenci_idkayit_sayisi
    22
    Aynı sonuca iki sayıyı karşılaştırarak da ulaşabilirsin:
    SELECT COUNT(*) AS toplam,
           COUNT(DISTINCT ogrenci_id) AS benzersiz
    FROM kayitlar;
    toplambenzersiz
    43
    İki sayı eşit değilse sütunda tekrar eden değer vardır. ogrenciler tablosunda aynı kontrolü yaptığında ikisi de 4 çıkar, çünkü birincil anahtar tekrar etmez.
  3. JOIN koşulunu gözden geçir. ON ifadesi var mı, doğru sütunları mı eşliyor, benzersiz olması gereken taraftaki sütun gerçekten benzersiz mi?

İlk iki adım bu yazıdaki Can örneğinde olduğu gibi ilişkiden doğan artışı, üçüncü adım ise sonraki bölümlerde ele alınan INNER JOIN ile LEFT JOIN davranışını, eksik koşulu ve yanlış sütunla eşleştirmeyi yakalar.

INNER JOIN ve LEFT JOIN satır sayısını nasıl etkiler?

Örneklerde ogrenciler tablosunda Ayşe (1), Can (2), Deniz (3) ve Elif (4) var. kayitlar tablosunda dört kayıt duruyor: 1 numaralı kayıt Ayşe'nin Matematik dersi, 2 numaralı kayıt Can'ın Fizik dersi, 3 numaralı kayıt Elif'in Kimya dersi, 4 numaralı kayıt Can'ın Python dersi. Deniz'in hiç kaydı yok.

INNER JOIN yalnızca eşleşenleri döndürür

SELECT o.ad, k.ders
FROM ogrenciler o
INNER JOIN kayitlar k ON o.ogrenci_id = k.ogrenci_id
ORDER BY o.ogrenci_id, k.kayit_id;

Beklenen çıktı 4 satırdır. Deniz'in karşı tarafta eşleşeni olmadığı için sonuçta görünmez:

adders
AyşeMatematik
CanFizik
CanPython
ElifKimya

LEFT JOIN soldaki tablonun her satırını korur

SELECT o.ad, k.ders
FROM ogrenciler o
LEFT JOIN kayitlar k ON o.ogrenci_id = k.ogrenci_id
ORDER BY o.ogrenci_id, k.kayit_id;

Beklenen çıktı 5 satırdır. Deniz artık listede, ders sütunu NULL olarak gelir:

adders
AyşeMatematik
CanFizik
CanPython
DenizNULL
ElifKimya

Satır sayısı tek başına doğruluk göstergesi değildir

LEFT JOIN sonucu, soldaki tablonun satır sayısının altına düşmez. Ama bir öğrenci karşı tarafta birden fazla kayıtla eşleşirse sayı bunun üstüne çıkabilir. Yukarıdaki 4 öğrenciye karşılık 5 satır tam olarak bunu gösteriyor.

INNER JOIN ise iki yönde birden etki eder: eşleşmeyenleri eler, çok eşleşenleri çoğaltır. Biri satır sayısını düşürüp diğeri yükselttiği için toplam tesadüfen beklediğin sayıya denk gelebilir. Bu yüzden "4 satır bekliyordum, 4 satır geldi" demek sonucun doğru olduğunu kanıtlamaz.

Eksik JOIN koşulu ve yanlış sütunla eşleştirme neden ayrı birer hatadır?

Eksik JOIN koşulu ve yanlış sütunla eşleştirme neden ayrı birer hatadır?

İkisi de satır sayısını bozabilir ama nedenleri farklıdır. Birinde eşleşme koşulu hiç yoktur, diğerinde koşul vardır ama yanlış şeyi karşılaştırır.

Eksik koşul: kartezyen çarpım

Eski virgüllü yazımda tablolar FROM satırında virgülle sıralanır, eşleşme koşulu ise WHERE içine yazılır. Koşul unutulursa veri tabanı elindeki tüm kombinasyonları üretir: her öğrenci her kayıtla eşleşir. Buna kartezyen çarpım denir.

SELECT COUNT(*)
FROM ogrenciler o, kayitlar k;
COUNT(*)
16

4 öğrenci ile 4 kaydın çarpımı 16 satır eder. Tabloların büyüklüğü arttıkça bu sayı hızla büyür; 1000 satırlık iki tablo bir milyon satır üretir. Koşulu WHERE o.ogrenci_id = k.ogrenci_id olarak eklediğinde sonuç yine 4 satıra iner. JOIN ... ON yazımında koşul sözdiziminin parçası olduğu için bu hatayı yapmak daha zordur.

Yanlış sütun: hata vermeyen sessiz bozulma

Koşul yazılmış ama anahtar olmayan bir sütunla kurulmuş olabilir:

SELECT o.ad, k.ders
FROM ogrenciler o
INNER JOIN kayitlar k ON o.ogrenci_id = k.kayit_id
ORDER BY o.ogrenci_id;

Sorgu sorunsuz çalışır ve 4 satır döndürür; sayı makul görünür. Ancak eşleşmelere bakınca sorun ortaya çıkar:

adders
AyşeMatematik
CanFizik
DenizKimya
ElifPython

İlk iki satır tesadüfen doğru. Ama kaydı hiç olmayan Deniz, Elif'in Kimya kaydıyla eşleşti; Elif'e de Can'ın Python kaydı yazıldı. Hata mesajı yok, satır sayısı da şüphe uyandırmıyor.

Karşılaştırdığın sütun iki tarafta da tekrar eden değerler içeriyorsa durum daha da kötüleşir: eşleşmeler çoğalır ve satır sayısı da şişer. Çıkarım şu: satır sayısı doğru görünse bile eşleşmelerin anlamını ayrıca kontrol etmelisin. Bir JOIN koşulunda yabancı anahtarın karşısına birincil anahtar gelmelidir; bu örnekte k.ogrenci_id, o.ogrenci_id ile eşleşmelidir.

DISTINCT neden sorunu çözmez, yalnızca gizler?

Satır sayısı arttığında akla ilk gelen çözüm SELECT DISTINCT eklemektir. Tekrar eden satırlar kaybolur ve sonuç düzelmiş gibi görünür:

SELECT DISTINCT o.ad
FROM ogrenciler o
INNER JOIN kayitlar k ON o.ogrenci_id = k.ogrenci_id;
ad
Ayşe
Mert
Zeynep

Üç ad döndü, ama JOIN yine dört satır üretti. DISTINCT yalnızca bu satırları en sonda tekilleştirdi. Sorgu sayma ya da toplamaya girdiğinde fark ortaya çıkar:

SELECT COUNT(*)
FROM ogrenciler o
INNER JOIN kayitlar k ON o.ogrenci_id = k.ogrenci_id;
COUNT(*)
4

Öğrenci sayısını soruyordun ama kayıt sayısını (4) aldın. Çoğalan satırlar sayıma da toplama da girer. Bu yüzden DISTINCT'i kök neden çözümü saymak yanlış olur.

Kök nedene inen iki çözüm

Kayıt sayısı gibi bir özet istiyorsan önce kayitlar tablosunu öğrenci başına tek satıra indir, sonra birleştir:

SELECT o.ad, k.kayit_sayisi
FROM ogrenciler o
INNER JOIN (
  SELECT ogrenci_id, COUNT(*) AS kayit_sayisi
  FROM kayitlar
  GROUP BY ogrenci_id
) k ON o.ogrenci_id = k.ogrenci_id;
adkayit_sayisi
Ayşe2
Mert1
Zeynep1

İhtiyaç yalnızca "kaydı olan öğrenciler" ise kayıt satırlarını sonuca taşımaya gerek yoktur. EXISTS her öğrenciyi en fazla bir kez döndürür:

SELECT o.ad
FROM ogrenciler o
WHERE EXISTS (
  SELECT 1 FROM kayitlar k
  WHERE k.ogrenci_id = o.ogrenci_id
);
ad
Ayşe
Mert
Zeynep

DISTINCT'in meşru bir yeri de var: sonuçta gerçekten tekrarsız değerler listelemek istiyorsan kullanabilirsin. Önemli olan bunu bilinçli bir tercih olarak yapmandır. Öğrencileri saymak istiyorsan COUNT(DISTINCT o.ogrenci_id) da çalışır, ama ad yerine anahtarı saymalısın. İki farklı öğrencinin adı aynı olabilir ve DISTINCT onları tek kişi gibi gösterir.

JOIN sonucunu doğrulamak için kısa kontrol listesi

Sorguyu çalıştırmadan önce ve çalıştırdıktan sonra bu sırayla ilerleyebilirsin:

  1. Sorguyu çalıştırmadan önce beklediğin satır sayısını tahmin et.
  2. İki tablo arasındaki ilişki türünü yaz: bire bir mi, bire çok mu?
  3. Karşı tablodaki anahtarı COUNT(*) ve COUNT(DISTINCT ...) ile karşılaştırarak benzersizliğini kontrol et.
  4. ON koşulunun var olduğunu ve doğru sütunları eşlediğini doğrula.
  5. Eşleşmeyen satırların sonuçta kalıp kalmayacağına göre INNER JOIN ya da LEFT JOIN seç.
  6. DISTINCT eklemeden önce satırların neden çoğaldığını bul.
  7. Toplam ya da sayı alırken önce özetle, sonra birleştir.

Beklenen sayıyı önceden tahmin etme ve sonucu bu tahminle karşılaştırma alışkanlığı SQL'in dışında da işe yarar. Algoritma yazarken ya da hata ayıklarken de aynı yolu izleyebilirsin. Seviyeni genel olarak ölçmek istersen ücretsiz bilgi testleri merkezine göz atabilirsin.

Bir JOIN'in sonucu beklediğinden büyükse önce satırların nereden geldiğine bak. Sorunun kaynağı çoğu zaman ilişki türü, anahtar ya da ON koşuludur.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara