Harun Reşit Zafer

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

SQL 18: Join Türleri

Önceki iki yazıda SQL’deki temel join sorguları üzerinde durmuştuk. O yazılarda anlatılan join’in en çok kullanılan türü olan inner join’di. Bu yazıda ise genel olarak inner, outer, left, right, full gibi join türlerinin benzer ve farklı yönlerini örneklerle açıklamaya çalışacağım. Eğer join konusuna tamamen yeni iseniz öncelikle ilk iki makaleyi çalışmanızı öneririm.

Bildiğiniz gibi üzerinde çalıştığımız veritabanları için kullanılan genel isim “ilişkisel veritabanı”dır. Yani tablolar birbiri ile ilişkilidir ve bu ilişki bir tablodaki birincil anahtar (primary key) ile diğer tablodaki yabancı anahtar (foreign key) üzerinden kurulur. Aşağıdaki okul veritabanında bu tablolar arasındaki ilişkiler açıkça görülüyor.

okul_vt_hrzafer

Join türlerini örneklendirmek için yukarıdaki tablolardan Öğrenci ve Bölüm tablolarını kullanalım:

Inner Join

Inner join en çok kullanılan join türüdür ve her iki tablodaki ortak kayıtları döndürür. Bir başka ifade ile iki tablonun kesişimini döndürür. Mesela bölüm ve öğrenci tablolarını birleştirmek istersek

SELECT * FROM bolum b INNER JOIN ogrenci o ON b.bid = o.bid

Sorgunun sonuç kümesi aşağıdaki gibi olacaktır.

bolum_ogrenci_inner

Sonuç kümesindeki ilk 4 kolon bölüm tablosunda sonraki 5 kolon ise öğrenci tablosuna aittir. Her iki tablonun bid alanlarına bakarsanız bire-bir eşleştiklerini görürsünüz. Yani sorgu iki tablonun kesişimini döndürmüş oluyor.

kümeler_inner

 

Left ve Right Outer join

Eğer bir tablodaki tüm kayıtlar ile diğer tablodaki birleştirme koşulunu sağlayan kayıtları döndürmek istersek right ve veya left outer join kullanırız.  Mesela tüm bölümleri (hiç öğrencisi olmayanlar da dahil) ve bir bölüme kayıtlı öğrencileri sorgulamak istersek:

SELECT * FROM bolum b LEFT JOIN ogrenci o ON b.bid = o.bid

bolum_ogrenci_left_outer

Son kayıda dikkat ederseniz hiç öğrencisi olmayan bölüm de sonuç kümesinde mevcut.  Yani soldaki tablodan (bölüm) tüm kayıtlar, sağdaki tablodan ise sadece kesişen kayıtlar gelmiş oldu.

kumeler_left_outer

Yukarıdaki sorguyuda  left (sol) yerine right (sağ) sözcüğünü kullanmış olsaydık, tüm öğrenciler ile en az bir öğrencisi olan bölümler seçilirdi. Yani left ve right tüm kayıtların seçileceği tablonun sağdaki mi yoksa soldaki mi olacağını belirtiyor yalnzıca.

SELECT * FROM bolum b RIGHT JOIN ogrenci o ON b.bid = o.bid

Bu sorguda tabloların yerini değiştirisek tekrar tüm bölümleri ve bir bölüme kayıtlı öğrencileri seçmiş oluruz.

SELECT * FROM ogrenci o RIGHT JOIN bolum b  ON b.bid = o.bid

Sadece sonuç kümesinde tabloların yeri değişmiş olur. Aşağıda görüldüğü gibi:

bolum_ogrenci_right_outer

Eğer yalnızca hiç öğrencisi olmayan bölümleri seçmek istersek where ifadesi ile öğrenci tablosundaki tüm kayıtları aşağıdaki gibi eleyebiliriz.

SELECT * FROM bolum b LEFT JOIN ogrenci o ON b.bid = o.bid WHERE o.bid IS NULL

bolum_ogrenci_left_only

Yaptığımız işlemi Venn şeması ile gösterecek olursak:

kumeler_left_only

 

Full Outer Join

Tüm öğrencileri ve tüm bölümleri seçmek istersek full outer  join kullanırız.

SELECT * FROM bolum b FULL OUTER JOIN ogrenci o ON b.bid = o.bid

Full outer join çok da gerekli olmadığından MySQL’de mevcut değildir. Ancak aşağıdaki gibi bir sorgu ile (union kullanarak) aynı sonuç elde edilebilir.

SELECT * FROM bolum b LEFT JOIN ogrenci o ON b.bid = o.bid
UNION
SELECT * FROM bolum b RIGHT JOIN ogrenci o ON b.bid = o.bid

Yaptığımız işlemi Venn şeması ile gösterecek olursak:

kumeler_full_outer

Sintaks

SQL join sintaksı ile ilgili olarak şunları hatırlatmakta yarar var.

Inner Join yerine sadece Join yazmamız yeterli

Left Outer Join yerine sadece Left Join yazmamız yeterli

Right Outer Join yerine sadece Right Join yazmamız yeterli

Natural Join

Bir de natural join var ki yazımda kolaylık sağladığı için öğrenciler tarafından tercih edilebiliyor.  Mesela aşağıdaki iki sorgu aynı işi yapar:

SELECT * FROM bolum b NATURAL JOIN ogrenci o
SELECT * FROM bolum b RIGHT JOIN ogrenci o ON b.bid = o.bid

Ancak gerçek hayatta Natural Join kullanımı sakıncalıdır.  Çünkü Natural Join iki tablodaki aynı isme sahip tüm alanların (kolonların) eşleşip eşleşmediğine bakar. Öğrenci ve Bölüm tablolarında sadece bid alanları aynı isme sahip olduğundan bir problem çıkarmıyor ancak Bölüm tablosunda bölümün ismini tutan için badi alanı adi şeklinde isimlendirilseydi Öğrenci tablosunda da aynı isimli bir alan bulunduğundan sorgu bu kez aşağıdaki sorgu ile eşdeğer olacaktı.

SELECT * FROM bolum b RIGHT JOIN ogrenci o ON b.bid = o.bid AND o.adi=b.adi

Kısacası natural join sorgusunda tam olarak hangi alanların karşılaştırıldığı belli değildir ve bu hata riskini artırtığı için profesyonel programcılar tarafından tercih edilmez.

Buradan okul veritabanını indirerek bu ve benzeri sorguları denemenizi öneririm. Umarım bu yazı sizler için faydalı olmuştur.

Herkese kolay gelsin

Kaynaklar

http://en.wikipedia.org/wiki/Join_%28SQL%29

http://www.sitepoint.com/understanding-sql-joins-mysql-database/

http://stackoverflow.com/questions/38549/difference-between-inner-and-outer-join

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

http://stackoverflow.com/questions/406294/left-join-and-left-outer-join-in-sql-server

http://www.wellho.net/mouth/158_MySQL-LEFT-JOIN-and-RIGHT-JOIN-INNER-JOIN-and-OUTER-JOIN.html

http://stackoverflow.com/questions/894490/sql-left-join-vs-multiple-tables-on-from-line/894659#894659

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

17 Yorum

  1. ellerinize sağlık hocam 🙂

  2. Merhabalar,

    Sitenizi yeni keşfettim. Join konusu çok kafa karıştırıcı ama gerçekten sade ve anlaşılır bir anlatımınız var.

    Paylaşımınız için çok teşekkürler.

  3. Sayın hocam anlatımlarınız çok sade ve açıklayıcı vıew konusuna da birazcık açıklık getirirseniz çok minnettar kalırım .Saygılar

  4. bizim ünievrsite hocası yanınınzda halt yemiş. mükemmel anlatım teşekkürler

  5. anlatımınız akıcı ve sade anlamadığım birçok konunun tamamını makaleleriniz sayesinde anladım,java ile mysql bağlantısı hakkında daha fazla bilgi paylaşmanız dileğiyle teşekkürler.

  6. iyi güzel hatta çok güçlü bir anlatım olmuş zaa XD

  7. Sql notlarının çok faydası oldu, çok teşekkür ediyorum

  8. Çok faydalı oldu elinize sağlık

  9. Muhammed Yemisenyayik

    30 Aralık 2014 at 00:35

    Sade ve açıklayıcı. Mukemmel.

  10. Hele şükür basit bir anlatımla karşılaştık ve en azından örnekler farklı. herkes aynı örneklerle aynı şekilde anlatmış. Sağolun

  11. mükemmel bir anlatım olmuş ellerinize sağlık.

  12. Ellerinize sağlık gerçekten çok güzel bir ders olmuş. Çok teşekkür ederim 🙂

  13. sesil akturk

    07 Ekim 2015 at 05:27

    teşekkürler verdiğiniz bilgiler çok yararli oldu..

  14. çok teşekkürler hocam..

  15. Hocam Ellerinize sağlık çok işime yaradı bu bilgiler.

  16. Güzel bir makale elinize sağlık. Bir video daha eğitici olabilirdi fakat görsellik kullanmanız çok iyi olmuş. Kolay gelsin iyi çalışmalar.

  17. dıger sıteler ıcerısınde en sade ve yalın anlatım tesekkurler

Bir Cevap Yazın

E-posta adresiniz yayınlanmayacak

*

© 2017 Harun Reşit Zafer

Temayı tasarlayanAnders NorenYukarı ↑