İçeriğe geç

Menü

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

SQL JOIN Sonuçları Neden Çoğalıyor? Satır Tekrarını Bulma ve Düzeltme

sql-join-sonuclari-neden-cogaliyor-satir-tekrarini-bulma-ve-duzeltme
Bu yazıda neler var?
  1. JOIN sonucu tek müşteri için neden birden fazla satır döndürür?
  2. customers ve orders örneğinde satır artışı nasıl görünür?
  3. Satır artışının kaynağı üç aşamada nasıl teşhis edilir?
  4. Beklenen bire çok ilişki ile hatalı eşleşme nasıl ayrılır?
  5. JOIN sonucu anlamı bozulmadan nasıl düzeltilir?
  6. Sık Sorulan Sorular

SQL JOIN sonuçları neden çoğalıyor sorusunun temel cevabı, JOIN işleminin koşulu sağlayan her kayıt çiftini ayrı bir sonuç satırı olarak döndürmesidir. Bir müşterinin birden fazla siparişi varsa müşteri sütunlarının her sipariş satırında tekrar görünmesi normaldir; ancak hatalı bir ON koşulu da beklenenden fazla eşleşme oluşturabilir.

Bu nedenle satır tekrarını düzeltmeden önce sonucun hangi varlık düzeyini temsil ettiğini, yani satır granülerliğini belirlemek gerekir. Aynı müşteri adının birkaç satırda görünmesi tek başına hata anlamına gelmez.

JOIN sonucu tek müşteri için neden birden fazla satır döndürür?

Bir JOIN sorgusunda sonuç satırı, soldaki tablodan bir kayıt ile sağdaki tablodan koşulu sağlayan bir kaydın oluşturduğu çifti temsil eder. Örneğin bir müşteri iki siparişe sahipse, müşteri ile birinci sipariş ve müşteri ile ikinci sipariş olmak üzere iki ayrı kayıt çifti oluşur. Sorgu bu çiftleri iki sonuç satırı olarak gösterir.

Satır granülerliği, sonuçtaki tek bir satırın neyi temsil ettiğini anlatır. Sadece müşteri bilgilerini döndüren bir sorgu müşteri düzeyinde olabilir. Müşteri ve sipariş bilgilerini birlikte döndüren sorgu ise çoğunlukla sipariş düzeyindedir. Bu durumda her satır bir siparişi temsil eder, müşteri bilgileri ise o siparişin sahibini belirtir.

  • Bire bir ilişkide: Her kayıt en fazla bir kayıtla eşleşiyorsa sonuç satırları genellikle aynı sayıda kalır.
  • Bire çok ilişkide: Bir sol kayıt, sağ tabloda kendisiyle eşleşen kayıt sayısı kadar sonuç satırı oluşturur.
  • Çoka çok ilişkide: Aynı anahtara bağlı m sol kaydı ve n sağ kaydı varsa eşleşmeler m × n sayısına ulaşabilir.

JOIN satırları çoğaltmaz; eşleşen kayıt çiftlerini görünür kılar.

Dolayısıyla aynı müşteri bilgilerinin farklı siparişlerde yinelenmesi, sorgunun sipariş granülerliğinde çalıştığını gösterebilir. Sorun, beklenmeyen eşleşmelerin oluştuğu veya sorgunun hedeflediği granülerliğin yanlış belirlendiği durumda ortaya çıkar.

customers ve orders örneğinde satır artışı nasıl görünür?

customers ve orders örneğinde satır artışı nasıl görünür?

Aşağıdaki örnekte bir müşterinin iki, diğer müşterinin bir siparişi bulunur:

CREATE TABLE customers (
    customer_id INTEGER PRIMARY KEY,
    customer_name VARCHAR(100) NOT NULL
);

CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    customer_id INTEGER NOT NULL,
    total_amount DECIMAL(10, 2) NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

INSERT INTO customers (customer_id, customer_name) VALUES
    (1, 'Ayşe'),
    (2, 'Mert');

INSERT INTO orders (order_id, customer_id, total_amount) VALUES
    (101, 1, 250.00),
    (102, 1, 125.50),
    (103, 2, 80.00);

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

Bu sorgunun sonucu üç satırdır:

customer_id customer_name order_id total_amount
1 Ayşe 101 250.00
1 Ayşe 102 125.50
2 Mert 103 80.00

Ayşe’nin müşteri bilgileri iki kez görünür çünkü iki farklı sipariş kaydıyla eşleşir. order_id değerleri farklı olduğu için bu satırlar özdeş kayıtlar değildir. Sorgu, müşterileri değil siparişleri gösterdiğinden üç satır üretmesi beklenen davranıştır.

Müşteri başına sipariş sayısını görmek için satırları GROUP BY ile müşteri düzeyinde özetleyebilirsin:

SELECT
    c.customer_id,
    c.customer_name,
    COUNT(o.order_id) AS order_count
FROM customers AS c
INNER JOIN orders AS o
    ON o.customer_id = c.customer_id
GROUP BY c.customer_id, c.customer_name
ORDER BY c.customer_id;
customer_id customer_name order_count
1 Ayşe 2
2 Mert 1

Satır artışının kaynağı üç aşamada nasıl teşhis edilir?

Satır artışının kaynağı üç aşamada nasıl teşhis edilir?

JOIN sonucundaki satır artışını teşhis ederken önce beklenen eşleşme sayısını hesapla, ardından ilişki anahtarlarını doğrula ve son olarak sorguyu adım adım çalıştır. Böylece artışın veri modelinden mi, kaynak veriden mi yoksa sorgu koşullarından mı geldiğini ayırabilirsin.

  1. Her anahtarın kaç eşleşme ürettiğini incele. Önce JOIN işleminin sağındaki tabloda, her müşteri için kaç sipariş bulunduğunu ölç:

    SELECT customer_id, COUNT(*) AS order_count
    FROM orders
    WHERE customer_id IN (101, 102)
    GROUP BY customer_id
    ORDER BY customer_id;

    Sonuçta 101 numaralı müşteri için 2, 102 numaralı müşteri için 1 sipariş görülüyorsa JOIN sonucunda toplam 3 satır beklenir. Müşteri tablosunda iki satır bulunmasına rağmen sonucun üç satır olması bu durumda hata değil, bire çok ilişkinin doğal sonucudur.

  2. Anahtarları, benzersizliği ve gerçek ilişki türünü kontrol et. customers.customer_id birincil anahtar, orders.customer_id ise yabancı anahtar olmalıdır. Yabancı anahtarın sipariş tablosunda tekrarlanması normaldir. Buna karşılık benzersiz olması beklenen müşteri anahtarındaki tekrarlar araştırılmalıdır:

    SELECT customer_id, COUNT(*) AS record_count
    FROM customers
    GROUP BY customer_id
    HAVING COUNT(*) > 1;

    Beklenen sonuç sıfır satırdır. Sorgu kayıt döndürürse aynı müşteri anahtarı kaynak tabloda birden fazla kez bulunuyor olabilir veya benzersizlik varsayımı şema kısıtıyla korunmuyor olabilir.

  3. WHERE ve JOIN adımlarını ayrı ayrı çalıştır. Önce temel satır sayısını, ardından her JOIN işleminden sonraki sayıyı karşılaştır:

    SELECT COUNT(*) AS customer_rows
    FROM customers
    WHERE customer_id IN (101, 102);
    
    SELECT COUNT(*) AS rows_after_orders_join
    FROM customers AS c
    JOIN orders AS o
      ON o.customer_id = c.customer_id
    WHERE c.customer_id IN (101, 102);

    İlk sorgunun sonucu 2, ikinci sorgunun sonucu 3 olmalıdır. Daha uzun bir sorguda diğer JOIN işlemlerini ve WHERE koşullarını tek tek ekle. Satır sayısının beklenmedik biçimde değiştiği ilk adım, incelenmesi gereken tabloyu veya koşulu gösterir.

Beklenen bire çok ilişki ile hatalı eşleşme nasıl ayrılır?

Ayırıcı ölçüt, satırların ekranda aynı görünmesi değil, farklı bir olguyu temsil edip etmemesidir. Aynı müşteri bilgisi farklı sipariş kimlikleriyle görünüyorsa satırlar birbirinin kopyası değildir.

Gözlem Olası açıklama Yapılacak kontrol
Aynı customer_id, farklı order_id değerleriyle görünüyor. Beklenen bire çok ilişki Müşteri başına sipariş sayısını ölç ve sipariş kimliklerinin farklı olduğunu doğrula.
Benzersiz olduğu düşünülen anahtar birden fazla kaynak kaydıyla eşleşiyor. Yanlış ilişki varsayımı veya kaynak veride tekrar Anahtarı GROUP BY ve HAVING COUNT(*) > 1 ile incele, şemadaki benzersizlik kısıtını kontrol et.
JOIN, ad, şehir veya durum gibi tekrarlanabilen sütunlarla kurulmuş. Hatalı ON koşulu Koşulu gerçek birincil anahtar ve yabancı anahtar ilişkisiyle karşılaştır.
İlişkiyi tanımlayan bileşik anahtarın yalnızca bir sütunu kullanılmış. Eksik ON koşulu Örneğin müşteri kimliğiyle birlikte şirket veya dönem kimliğinin de gerekli olup olmadığını denetle.
Her iki tabloda da eşleşen birden fazla kayıt bulunuyor. İstenmeyen çoklu eşleşme İki taraftaki eşleşme sayılarını ayrı ayrı ölç ve JOIN koşulunun ilişkiyi yeterince sınırlandırıp sınırlandırmadığını kontrol et.

Görünür tekrar, seçilen sütunların aynı olmasıdır. Örneğin yalnızca müşteri adını seçmek, farklı order_id değerlerini gizleyebilir. Teşhis sırasında iki tablonun anahtarlarını da SELECT listesine eklemek, satırların gerçekten aynı mı yoksa yalnızca benzer mi olduğunu gösterir. Kaynak verideki gerçek mükerrerlik ise aynı varlığı tanımlayan anahtarın, veri modeline aykırı biçimde birden fazla kaynak satırında bulunmasıdır.

JOIN sonucu anlamı bozulmadan nasıl düzeltilir?

Önce satırları azaltmaya değil, istenen sonuç düzeyini belirlemeye odaklan. Sipariş ayrıntısı gerekiyorsa bir müşteriye ait birden fazla siparişi gösteren satırları korumak doğrudur. Müşteri başına tek özet gerekiyorsa COUNT veya SUM gibi toplulaştırmalarla GROUP BY kullanabilirsin.

Yalnızca siparişi bulunan müşterileri listelemek istiyorsan, sipariş tablosundaki sütunlara ihtiyaç duymadan EXISTS kullanmak daha uygun olur:

SELECT c.customer_id, c.customer_name
FROM customers AS c
WHERE EXISTS (
    SELECT 1
    FROM orders AS o
    WHERE o.customer_id = c.customer_id
)
ORDER BY c.customer_id;

Örnek çıktı:

customer_id | customer_name
1           | Ayşe
2           | Mehmet

Ayşe'nin birden fazla siparişi olsa bile EXISTS, eşleşmenin varlığını kontrol eder ve müşteriyi bir kez döndürür. Yanlış eşleşme varsa çözüm, sonucu gizlemek değil, JOIN ON koşulunu düzeltmektir. İlişki tekil bir anahtara dayanıyorsa o anahtarı, bileşik anahtara dayanıyorsa anahtarın tüm sütunlarını koşula ekle. Aksi hâlde farklı kayıtlar aynı müşteri, kod veya dönem bilgisi üzerinden yanlış biçimde eşleşebilir.

DISTINCT yalnızca seçilen sütunların tamamı aynı olan satırları birleştirir. Farklı sipariş kimlikleri veya tutarlar seçiliyorsa satırlar farklı kabul edilir ve satır sayısı azalmaz. Bu sütunları seçmeden DISTINCT kullanmak ise çoğalmayı gizleyerek sipariş ayrıntısının kaybolmasına yol açabilir; bu nedenle hatalı JOIN koşulunun yerine geçmez.

Uygulama kontrol listesi:

  1. Hedef satır düzeyini belirle: sipariş ayrıntısı mı, müşteri özeti mi, yalnızca varlık kontrolü mü?
  2. Eşleşme anahtarını doğrula ve gerekiyorsa bileşik anahtarın tüm parçalarını kullan.
  3. Çözüm yöntemini seç: ayrıntıyı koru, GROUP BY ile özetle veya EXISTS ile varlığı denetle.
  4. Satır sayısını ve örnek kayıtları yeniden karşılaştır.

Sık Sorulan Sorular

LEFT JOIN neden tek müşteri için birden fazla satır döndürür?

Sol tablodaki bir müşteri, sağ tablodaki birden fazla siparişle eşleşiyorsa LEFT JOIN her eşleşme için ayrı satır üretir. Hiç eşleşme yoksa müşteri genellikle bir kez, sağ tablo sütunları boş değerlerle döner.

DISTINCT kullandığım hâlde satır sayısı neden azalmıyor?

Seçilen sütunlardan en az biri satırlar arasında farklıdır. Sipariş kimliği, tarih veya tutar gibi değerler farklı kaldığı sürece DISTINCT bu satırları aynı kabul etmez.

JOIN koşulunda bileşik anahtarın bir sütununu unutmak sonucu nasıl etkiler?

Koşul eksik kaldığında farklı anahtar parçalarına sahip kayıtlar da eşleşebilir. Bu durum yanlış kombinasyonlar ve beklenenden fazla satır oluşturur.

GROUP BY ile EXISTS arasında nasıl seçim yapılır?

Her müşteri için toplam, adet veya başka bir özet hesaplayacaksan GROUP BY kullan. Yalnızca müşterinin en az bir siparişi olup olmadığını kontrol edeceksen EXISTS daha doğrudan bir seçimdir.

Doğru çözüm, çoğalan satırları otomatik olarak silmek değil, sorgunun üretmesi gereken satır düzeyini korumaktır.

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