Harun Reşit Zafer

bâki kalan bu kubbede bir hoş sadâ imiş

SQL 13: Sorguda Birden Fazla Tablo Kullanma: Join-2

Schema SQL
2 veya daha fazla tablonun belirli kolonları arasındaki ilişkilere dayanarak bu tablolardan veri çekme işlemine JOIN denir. Bu işlem için JOIN anahtar kelimesi kullanılır ama zorunlu değildir. Bir önceki yazıda ilişkili 2 tablo için yazdığımız join sorgularımızın hiçbirinde JOIN anahtar sözcüğünü kullanmamıştık. Bu yazıda hem JOIN anahtar sözcüğünün kullanımını hem de ilişkili 3 tablo için sorgu yazılışını anlatmaya çalışacağım.

Not: Bu arada diğer SQL derslerine buradan ulaşabilirsiniz

Ama önce biraz ısınmak için tabloları ve sorgumuzu hatırlayalım. Bu iki tablo arasındaki ilişkiyi yayınevleri tablosundaki no alanı ile Kitaplar tablosundaki yv_no (yayınevi no) alanlarının sağladığını tekrar hatırlatalım. Aslında yv_no alanı Yayınevleri tablosunun birincil anahtarı (primary key) olan no alanını referans göstermektedir. Bir tabloda, başka bir tablonun birincil anahtar alanını referans gösteren alanlara yabancı anahtar (foreign key) diyoruz. Burada da yv_no alanı yabancı anahtar konumunda. Örneğin Yayınevleri tablosunda 5 nolu bir yayınevi olmadığına göre Kitaplar tablosundaki yv_no alanı değerini alamaz. yv_no alanının bu örnekte alabileceği değerler 1, 2 ve 3’tür. Ancak 5 nolu bir yayınevi Yayınevleri tablosuna eklendikten sonra yv_no alanı da 5 değerini alabilir.

Yukarıdaki paragrafın Türkçesi: 5 nolu bir yayınevi olmadığına göre 5 nolu yayınevi tarafından basılmış kitap/kitaplar da olamaz.

Yayınevleri Kitaplar

no

isim

sehir

1 A Ankara
2 B İstanbul
3 C İzmir

no

isim

yv_no

1 5 dakkada Java 1
2 5 bilemedin 6 saatte SQL 1
3 Hakiki SQL 2

Hangi kitabın hangi yayınevi tarafından basıldığını gösteren sorgu (JOIN anahtar sözcüğünü kullanmadan)

SELECT K.isim, Y.isim FROM kitaplar K, yayinevleri Y WHERE K.yv_no = Y.no

Yukarıdaki soru ile tamamen aynı işi yapan bu sorguda ise JOIN anahtar sözcüğünü kullanalım:

SELECT K.isim, Y.isim FROM kitaplar K INNER JOIN yayınevleri Y ON Y.no = K.yv_no

Her iki sorgunun da çıktısı aşağıdaki gibi olacaktır:

isim isim
5 dakkada Java A
5 bilemedin 6 saatte SQL A
Hakiki SQL B

Birbiri ile ilişkili 3 tablo için join sorgularının nasıl yazılacağına bakmadan önce bize 3 tablo gerekiyor.

Bu yüzden veritabanımıza yazarları da dahil edelim. Ancak bir yazarın birden fazla kitabı olabileceği gibi bir kitabın da birden fazla yazarı olabilir. Bu da kitap ve yazar tabloları arasında çoğa-çok ilişki olduğunu gösteriyor. Oysa kitap ile yayınevi tabloları arasındaki ilişki bire-çok şeklindedir. Yani bir yayınevi birden fazla kitap basabilir ancak bir kitap yalnızca bir yayınevi tarafından basılabilir.

Çoğa-çok ilişkili varlıkları ifade edebilmek için veritabanına 3. bir tablo eklememiz gerekiyor. Burada bu tablonun adı KitapYazar.  KitapYazar tablosuna şöyle bir baktığımızda 1 nolu kitabı 2 nolu yazarın yazdığını, 3 nolu kitabı 1 ve 2 nolu yazarların yazdığını ya da 2 nolu yazarın 1 ve 3 nolu kitapların yazarı olduğunu görebiliyoruz.

Kitaplar KitapYazar Yazarlar
no isim yv_no
1 5 dakkada Java 1
2 5 bilemedin 6 saatte SQL 1
3 Hakiki SQL 2
kno yno
1 2
2 3
3 1
3 2
no isim ulke
1 Nihat Veritabanı Türkiye
2 Muharrem Nesnel Türkiye
3 Taylan Esquel Meksika

Hangi kitabı hangi yazarın yazdığını isim isim listelemek istememiz durumunda 3 tabloyu da kullanan bir JOIN sorugusu yazmamız gerekir.

SELECT * FROM kitaplar K , yazarlar Y, kitapyazar KY WHERE K.no=KY.kno AND Y.no=KY.yno

veya

SELECT * FROM kitaplar K INNER JOIN kitapyazar KY ON K.no= KY.kno INNER JOIN yazarlar Y ON KY.yno=Y.no

Her iki sorgunun da çıktısı aşağıdaki gibi olacaktır:

no isim yv_no kno yno no isim ulke
1 5 dakkada Java 1 1 2 2 Muharrem Nesnel Türkiye
2 5 bilemedin 6 saatte SQL 1 2 3 3 Taylan Esquel Meksika
3 Hakiki SQL 2 3 1 1 Nihat Veritabanı Türkiye
3 Hakiki SQL 2 3 2 2 Muharrem Nesnel Türkiye

Sonuç tablosunu daha sade istersek sorgularımızı yalnızca isim alanlarını getirecek şekilde düzenleyebiliriz:

SELECT K.isim,  Y.isim FROM kitaplar K , yazarlar Y, kitapyazar KY WHERE K.no=KY.kno AND Y.no=KY.yno

veya

SELECT K.isim, Y.isim FROM kitaplar K JOIN kitapyazar KY ON K.no= KY.kno JOIN yazarlar Y ON KY.yno=Y.no

Dikkat ederseniz bu sorguda INNER anahtar sözcüğünü kullanmadım çünkü aksini belirtmedikçe (yani INNER yerine outer, right, left anahtar sözcükleri ile join’in türünü belirtmedikçe) varsayılan olarak INNER JOIN işlemi yapılacaktır. Başka bir ifade ile “abi ben OUTER, RIGHT, LEFT join nedir bilmem, bana bildiğimiz JOIN lazım diyorsanız” ben de “kardeş INNER yazmasan da olur” diyorum.

Her iki sorgunun da çıktısı aşağıdaki gibi olacaktır:

isim isim
5 dakkada Java Muharrem Nesnel
5 bilemedin 6 saatte SQL Taylan Esquel
Hakiki SQL Nihat Veritabanı
Hakiki SQL Muharrem Nesnel

 

Sonuç olarak bu yazı beni pek tatmin etmedi. Daha samimi bir ifade ile “içime sinmedi”. Çünkü JOIN konusu veritabanı tasarımı ile doğrudan alakalı ve birincil anahtar, yabancı anahtar, tablo ilişkileri gibi bir çok kavramın önceden anlaşılmış olması gerekiyor ki bu konu tam olarak anlaşılabilsin. Yukarıda biraz bahsetmeye çalıştım ama aslında 4-5 makale ile ayrıntılı ele alınması gereken ve SQL çalışmaya başlamadan önce öğrenilmesi gereken konular bunlar.

İnşaallah bu yazı faydalı olmuştur ve umarım vaktim olur da veritabanı tasarımı konusunu detaylı olarak ele alabilirim.

Herkese Kolay Gelsin

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInPrint this pageEmail this to someone

21 Yorum

  1. hocam dediğiniz gibi 1. ve 2.makaleyi okudum ancak bnm demek istediğim biraz farklı..
    adaylartablosu:
    isim soyad yas egitimseviyesi
    musteritablosu:
    isim soyad yas egitimseviyesi
    şeklinde aynı kolonlara sahipse
    adaylar uygun görüldüğünde müşteri tablosunda gözüksün..yani tek bir tabloda aday da artık bir müsteri olarak kayıt edilsin..
    ben tablodoldur() methodunda Select * from adaylartablosu,musteritablosu dedimde iki tablo yanyana gösteriliyor..umarım anlatabilmişimdir..

  2. Sonuç bölümünde de belirtiğiniz üzere JOIN aslında çok geniş kapsamlı incelenmesi ve mutlaka öğrenilmesi gereken bir konu. Öncelikle bu konu için yaptığınız basit giriş için bilmeyenler adına teşekkür ederim. Fakat yazı içinde adı geçen LEFT, RIGHT gibi join işlemleri için yapılan açıklama bu mini makalede eksik kalmış gibi görünüyor.Onuda ben eklemek istedim:

    LEFT JOIN: Sol tablodaki tüm kayıtarı ve sağ tablodaki eşleşen kayıtları getirir.

    RIGHT JOIN: Sağ tabloadaki tüm kayıtları ve sol tabloadaki eşleşen kayıtları getirir.

    Dipnot: LEFT JOIN ve RIGHT JOIN bazı veritabanlarında LEFT OUTER JOIN ve RIGHT OUTER JOIN olarak kullanılıyor olabilir.

    Hocamın verdiği örneklerden yola çıkarak:
    SELECT * FROM kitaplar k LEFT JOIN kitapyazar ky ON k.no = ky.kno

    Yukarıdaki örnek kitaplar tablosundaki tüm kayıtları (örn: 10 kayıt varsa bunların tümünü) ve kitapyazar tablosundan k.no = ky.kno koşulu ile eşleşen kayıtları getirecektir.

    Aslında vakitiniz varsa LEFT ve RIGHT JOIN ile ilgili bir makale yayınlamanız ve niçin, neden kullanıldığını anlatsanız birçok insan bu konuda daha iyi fikir sahibi olabilir diye düşünüyorum.

    Dipnot: SQL komutlarını yazarken insanları korkutmamak adına bence şöyle bir kullanım şekli seçin (Satır Satır):

    SELECT *
    FROM kitaplar K
    INNER JOIN kitapyazar KY ON K.no= KY.kno
    INNER JOIN yazarlar Y ON KY.yno=Y.no

    Bu kullanım insanların kodları satır satır inceleyip her satırın ne için kullanıldığını anlayabilmesi için bence daha iyi bir yol.

    Teşekkürler.

  3. Muharrem ARAS

    24 Haziran 2011 at 18:15

    Teşekkürlerimi sunuyorum…

  4. Ufuk ADIYAMAN

    30 Aralık 2011 at 01:25

    Hocam ;

    SELECT K.isim, Y.isim FROM kitaplar K, yayinevleri Y WHERE K.yv_no = Y.no

    Bu kısımda tabloların no ve yv_no larını bağlamamız gerekmiyor mu ?

  5. Ufuk ADIYAMAN

    30 Aralık 2011 at 01:30

    pardon :) hatamı gördüm :)

  6. Allah razı olsun güzel bir çalışma.

  7. ben isim tablosunu bulamiyorum

  8. Hocam Elinize sağlık. Ama 4. kod bloğundaki kodlar birebir aynı tabloyu vermiyor. Tablo sırası fark ediyor :)

  9. Kardeş eline sağlık gayet yalın bir dille temiz bir anlatım olmuş

  10. hocam peki “where” komutunu kullanırken koşulu metin dosyasından nasıl alabiliriz k.no=KY.yno yerine k.no=metin22.text benzeri bir komuta ihtiyacım var
    örneğin
    SELECT * FROM kitaplar K , yazarlar Y, kitapyazar KY WHERE K.no=metin22.text

    • Bunun için bir programlama diline ihtiyacınız var. Java gibi bir dil ile dosya okuyup SQL komutlarını bu programalama dili üzerinden çalıştırmanız gerekiyor. Sitedeki Java MySQL yazılarına göz atmanızı tavsiye ederim.

  11. salam. meqalenizde gösterdiğiniz 3 tablo arasında elaqe (ilişki) qurarken “foreign key”-i nece olur? 2 tablo arasında gösterdiğiniz kimi etdim,ama yanlış oldu. sorum çox basit ola biler, yeni başladığım üçün zor anlıyıram ((

  12. salam. meqalenizde gösterdiğiniz 3 tablo arasında ilişki kuran zaman foreign key”i nasıl oluyr? yeni başladığım için sorum basit ola bilir, ama cevaplarsanız sevinirim

    • Yayınevi ile Kitap arasındaki ilişki Kitap tablosundaki yv_no il yayinevi tablosundaki no alanı üzerinden kuruluyor
      KitapYazar tablosunda ise kno Kitap tablosundaki no alanına referans bir foreign key. Aynı şekilde yno da Yazar tablosundaki no alanına ref. bir foreign key. Bu iki FK birlikte bu tablonun primary key’ini oluşturuyorlar.

  13. Ellerine sağlık hocam. Hiç bu kadar açık ve net bir şekilde anlatan bir kaynakla karşılaşmadım. Düşündüğüm kadar zor bir konu değilmiş.

  14. Merhabalar; Yukarıdaki kodlarda joinli ve joinsiz kullanım mevcut. Ama genelde tabloları birleştirirken join kullanılmakta. Bunun sebebi nedir aceba? Cevaplarsanız sevinirim. Kolay gelsin…

Bir Cevap Yazın

E-posta adresiniz yayınlanmayacak

*

© 2016 Harun Reşit Zafer

Temayı tasarlayanAnders NorenYukarı ↑