Ö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.
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.
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.
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
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.
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:
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
Yaptığımız işlemi Venn şeması ile gösterecek olursak:
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:
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
25 Ocak 2013 at 14:29
ellerinize sağlık hocam 🙂
28 Ocak 2013 at 01:41
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.
03 Nisan 2013 at 16:38
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
20 Mayıs 2013 at 22:23
bizim ünievrsite hocası yanınınzda halt yemiş. mükemmel anlatım teşekkürler
20 Haziran 2013 at 16:53
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.
19 Eylül 2013 at 02:55
iyi güzel hatta çok güçlü bir anlatım olmuş zaa XD
15 Nisan 2014 at 01:09
Sql notlarının çok faydası oldu, çok teşekkür ediyorum
06 Eylül 2014 at 07:34
Çok faydalı oldu elinize sağlık
30 Aralık 2014 at 00:35
Sade ve açıklayıcı. Mukemmel.
03 Mart 2015 at 03:07
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
20 Ağustos 2015 at 09:05
mükemmel bir anlatım olmuş ellerinize sağlık.
08 Eylül 2015 at 04:13
Ellerinize sağlık gerçekten çok güzel bir ders olmuş. Çok teşekkür ederim 🙂
07 Ekim 2015 at 05:27
teşekkürler verdiğiniz bilgiler çok yararli oldu..
13 Kasım 2015 at 17:01
çok teşekkürler hocam..
14 Aralık 2015 at 04:30
Hocam Ellerinize sağlık çok işime yaradı bu bilgiler.
19 Temmuz 2016 at 07:32
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.
20 Aralık 2016 at 14:23
dıger sıteler ıcerısınde en sade ve yalın anlatım tesekkurler
29 Eylül 2017 at 12:42
Sayın hocam harika anlattınız çok teşekkür ediyorum. Emeğiniz için teşekkürler.
11 Şubat 2019 at 06:34
Emeğinize sağlık, teşekkürler..
07 Mayıs 2019 at 01:32
harika olmuş eline sağlık hocam çok yararlı oldu 🙂
24 Ağustos 2019 at 11:22
Teşekkürler sayenizde anladım
29 Ocak 2020 at 15:21
haRİKA ÇOK AÇIKLAYICI OLMUŞ