SQL'de Bir Tabloyu Kendisiyle Birleştirmek: Self Join
Beceri rehberi

SQL'de Bir Tabloyu Kendisiyle Birleştirmek: Self Join

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Self join nedir, takma adlarla bir tablo kendisiyle nasıl birleştirilir? Çalışan-yönetici örneği, eşleşme ve tekrar sorguları, yaygın hatalarla açıklanır.

Self join nedir ve ne zaman gerekir?

Self join, bir tablonun kendi kendisiyle birleştirilmesidir. Yeni bir JOIN türü değildir; INNER JOIN ya da LEFT JOIN gibi bilinen birleştirmelerin aynı tabloya birden fazla kez başvurması şeklinde uygulanmasıdır. Sistem tabloyu ayrı kopyalarmış gibi ele alır ve satırları birbirleriyle eşleştirir.

Bu yaklaşım, tablonun içinde satırların birbirine bağlandığı durumlarda gerekir. En tipik örnek hiyerarşidir: çalışanlar tablosunda her satırın yönetici sütunu, aynı tablodaki başka bir çalışanın numarasını gösterir. Bir çalışanın yöneticisinin adını görmek için tabloyu kendisiyle eşlemek gerekir. Benzer yapılar kategori ağaçlarında (üst kategori), ürün ağaçlarında (üst ürün) ve organizasyon şemalarında görülür.

Self join yalnızca hiyerarşi için değildir. Aynı tablodaki satırları birbirleriyle karşılaştırmanız gereken her durumda kullanılır: aynı şehirdeki müşteri çiftlerini bulmak, aynı gün işlem yapan kullanıcıları eşlemek ya da bir satırı önceki satırıyla kıyaslamak gibi.

Sözdizimi: takma ad (alias) zorunludur

Self join'in tek kritik kuralı, tablonun her kopyasına farklı bir takma ad vermektir. Takma ad olmadan sistem hangi kopyayı kastettiğinizi anlayamaz ve belirsiz sütun hatası verir.

Kalıp şöyledir: FROM employees AS c, ardından JOIN employees AS y, ve son olarak ON c.manager_id = y.employee_id. Burada c çalışanı, y yöneticiyi temsil eder. SELECT satırında c.ad AS employee ve y.ad AS manager yazarak kopyalardan gelen sütunları ayırt edersiniz.

Takma adlara anlamlı isimler seçmek okunabilirliği ciddi biçimde artırır. a ve b gibi harfler küçük sorgularda yeterli görünür ama JOIN koşulu karmaşıklaştığında hangi tarafın ne olduğu unutulur. Çalışan ve yönetici, alt ve üst, önceki ve sonraki gibi rolü anlatan adlar daha güvenlidir. AS anahtar kelimesi bazı sistemlerde tablo takma adında isteğe bağlıdır; yine de açık yazmak alışkanlık olarak iyidir.

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

Örneğin çalışanlar tablosunda employee_id, ad, departman ve manager_id sütunları olsun. En üstteki kişinin manager_id değeri boştur (NULL).

Çalışanları yöneticileriyle listelemek için tabloyu kendisiyle birleştirirsiniz. INNER JOIN kullanırsanız yöneticisi olmayan, yani en üstteki kişi sonuçtan düşer; çünkü eşleşecek satırı yoktur. Tüm çalışanları görmek, yöneticisi olmayanlar için de boş yönetici adıyla satır almak istiyorsanız LEFT JOIN kullanın. Bu tercih, self join'de en sık yapılan hatanın tam kaynağıdır: eksik satırların fark edilmeden raporlanması.

Aynı tabloyu ters yönde de sorgulayabilirsiniz. Her yöneticinin kaç kişiye yönetici olduğunu görmek için yönetici tarafını sabit tutup çalışan tarafını sayarsınız; bunun için JOIN'e GROUP BY ve COUNT eklenir. Hiç ekibi olmayan çalışanları bulmak içinse LEFT JOIN ile eşleşmeyen satırları (WHERE sağ taraf IS NULL) filtrelemek yeterlidir.

Aynı özelliği paylaşan satır çiftlerini bulmak

Self join'in bir diğer büyük kullanımı, aynı tablodaki satırları çiftler halinde eşlemektir. Örneğin müşteriler tablosunda aynı şehirde yaşayan müşteri çiftlerini listelemek istiyorsunuz. Tabloyu müşteri a ve müşteri b olarak farklı takma adlarla bağlar, JOIN koşuluna a.sehir = b.sehir yazarsınız.

Burada hemen sorunlar ortaya çıkar. Önce her satır kendisiyle de eşleşir; çünkü kendi şehri kendisiyle aynıdır. Ayrıca çiftler karşılıklı olarak tekrar eder: (Ayşe, Mehmet) ile (Mehmet, Ayşe) ayrı satırlar olarak gelir. Çözüm, JOIN koşuluna a.customer_id < b.customer_id eklemektir. Bu tek karşılaştırma hem kendi kendiyle eşleşmeyi hem ters çiftleri eler.

Aynı kalıp, tekrar eden kayıtları bulmak, aynı e-postayı paylaşan hesapları yakalamak ya da fiyat aralığı örtüşen ürünleri bulmak için de kullanılır. Eşitsizlik koşulu burada pencere görevi görür.

Self join ne zaman uygun değildir?

Her karşılaştırma için self join uygun araç değildir. Bir satırı önceki ya da sonraki satırla kıyaslamak istiyorsanız modern veritabanı sistemlerindeki LAG ve LEAD pencere fonksiyonları çoğunlukla daha sade ve daha hızlıdır. Kümülatif toplam ve sıralama gibi işler de pencere fonksiyonlarıyla daha okunaklı yazılır.

Hiyerarşi derinse, yani bir kişinin yöneticisinin yöneticisinin yöneticisini bulmak gerekiyorsa, her seviye için bir self join eklemek hızla yönetilemez hale gelir. Derinliği önceden bilinmeyen ağaçlarda recursive CTE (özyinelemeli ortak tablo ifadesi) bu iş için tasarlanmıştır; her seviyeyi tek bir sorgu yapısıyla dolaşır.

Büyük tablolarda self join maliyetlidir, çünkü tablonun kendisiyle çarpımı oluşur. JOIN koşulundaki sütunlarda indeks bulunması ve eşitsizlik koşullarını mümkün olduğunca daraltmak, sorgunun makul sürede çalışması için belirleyicidir.

Sık yapılan hatalar

Self join yazarken tekrar eden hatalar şunlardır: • Takma adı eksik bırakmak ya da aynı adı tüm kopyalara vermek: sistem sütunların hangi kopyaya ait olduğunu çözemez. • SELECT satırında tablo adı olmadan sütun yazmak: ad gibi ortak sütunlar belirsiz hale gelir; her sütunun önüne takma ad koyun. • Yanlış JOIN türü seçmek: hiyerarşide en üstteki satırın kaybolmasına yol açar. Sonuçta kaç satır beklediğinizi sorgudan önce tahmin edip karşılaştırın. • Eşleşmede çiftlerin karşılıklı tekrar etmesini görmemek: sıralama koşuluyla (küçüktür) yalnızca bir yönü alın. • NULL karşılaştırması: manager_id = manager_id gibi koşullar NULL değerlerde eşleşmez; NULL'ları ayrıca düşünmek gerekir. • Hiyerarşide döngü: bir kaydın kendi altındaki biri tarafından yönetici gösterilmesi gibi veri hataları self join ve recursive sorgularda sonsuz ya da yanıltıcı sonuç doğurabilir; veri kalitesini önce kontrol edin.

Nasıl çalışılır, nereden başlanır?

Self join'i anlamanın en kısa yolu küçük bir tabloyla elle denemektir. Birkaç satırlık bir çalışan tablosu oluşturun, tabloyu kopyalar halinde kafanızda yan yana koyun ve hangi satırın hangisiyle eşleştiğini kâğıt üzerinde izleyin. Sonra aynı sorguyu çalıştırıp sonucu karşılaştırın.

Öğrenme sırası olarak önce INNER ve LEFT JOIN, takma ad kullanımı ve NULL davranışı rahat olmalı. Ardından self join, sonra pencere fonksiyonları ve recursive CTE gelir.

Mindset kataloğunda SQL ile Veri Sorgulama (Temel) eğitimi, filtreleme, toplulaştırma ve tablo birleştirme (JOIN teknikleri) modüllerini içerir. SQL ile Programlama Eğitimi ise Join Kullanımı ile Toplama ve Gruplama modüllerini kapsar. Bu modüller, veri raporlaması yapan analist ve destek ekipleri için self join'in dayandığı temel birleştirme mantığını verir; takım içinde ortak sorgu alışkanlığı oluşturmak isteyen kurumlar aynı müfredatı kullanabilir.

İlgili Mindset programı

SQL ile Veri Sorgulama (Temel)

Sık sorulanlar

Sık sorulan sorular

Self join ayrı bir JOIN türü müdür?

Hayır. Self join, standart JOIN türlerinin (INNER, LEFT) aynı tabloya birden fazla kez başvuracak şekilde kullanılmasıdır. Özel bir anahtar kelimesi yoktur; tabloya farklı takma adlar verip JOIN koşulunda bu takma adları karşılaştırırsınız. Veritabanı sistemi tabloyu bağımsız kaynaklar gibi işler.

Self join'de takma ad kullanmak neden zorunlu?

Aynı tablo adı sorguda birden fazla geçtiğinde, sütun başvurusunun hangi kopyaya ait olduğu belirsiz kalır. Takma adlar her kopyayı ayırt eder: c.ad ile çalışanın, y.ad ile yöneticinin adı seçilir. Takma ad vermezseniz sistem belirsiz sütun hatası döndürür.

Çalışan ve yönetici sorgusunda en üstteki kişi neden görünmüyor?

En üstteki kişinin yönetici sütunu boştur, yani eşleşecek satırı yoktur. INNER JOIN eşleşmeyen satırları eler. Bu kişiyi de listelemek için LEFT JOIN kullanın; yönetici adı bu satırda boş (NULL) görünür. Sonucu COALESCE ile okunabilir bir metne çevirebilirsiniz.

Self join yerine ne zaman pencere fonksiyonu kullanmalıyım?

Satırı önceki ya da sonraki satırla karşılaştırmak, sıra numarası vermek veya kümülatif toplam almak gibi işlerde LAG, LEAD ve diğer pencere fonksiyonları daha sade yazılır ve çoğu durumda daha verimli çalışır. Self join, satırların bir anahtar üzerinden birbirine bağlandığı hiyerarşi ve çift eşleştirme işlerinde öne çıkar.

Self join çok yavaşsa ne yapmalıyım?

Önce JOIN koşulunda kullanılan sütunlarda indeks olup olmadığına bakın. Ardından WHERE ile tabloyu önceden daraltın ve eşitsizlik koşullarını sıkılaştırın. Yürütme planını inceleyerek tablonun tamamının mı taranıp çarpıldığını doğrulayın. Derin hiyerarşilerde recursive CTE de daha uygun bir çözüm sunabilir.

SQL Self Join: Kendi Kendine Birleştirme Nasıl Yapılır