MSSQL ve diğer veritabanı yönetim sistemleri üzerinde, eğer iyi tasarlanmış bir veritabanı ile çalışılıyorsa birden fazla tablo üzerinde çalışma zorunluluğu ortaya çıkmaktadır. Bu sebeple özellikle listeleme sorgularında verilerin anlamlı bir şekilde gösterilebilmesi için birden fazla tablonun, verilerin gösterimi aşamasında ortak alanlar üzerinden birleştirilerek sunulması gerekmektedir.
JOIN Nedir?
JOIN işlemi, veritabanı üzerinde bir veya birden fazla tablonun birleştirilerek gösterilmesidir. Tablo birleştirme işlemlerinin gerekli olduğu tüm sorgularda kullanılabilirken daha çok SELECT sorgularında karşımıza çıkar. JOIN ile tablolar, yalnızca sorgulama esnasında birleşik gibi görünürler ancak aslında bu tablolar birbirinden ayrıdırlar. Ancak ortak alan aracılığıyla bu tablolar bağlantılı olabilirler.
Tüm JOIN sorgularında ortak bir alan belirtmek zorunludur. Bu ortak alan ON ifadesinden hemen sonra, eşitlik ifadesi belirtilmektedir.
1 | SELECT * FROM ogrenci INNER JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no |
Bu örnek sorguda ogrenci tablosunda kulup_no alanı ile kulup tablosundaki kulup_no alanlarının birbirleriyle ilişkili oldukları anlatılmaktadır.
JOIN Çeşitleri Nelerdir?
JOIN sorguları, verileri elde etmek istediğimiz şekle göre aşağıdakiler gibi olabilirler:
- INNER JOIN (Kümelerde kesişim işlemi)
- LEFT JOIN (WHERE … IS NULL ile kullanılırsa fark işlemi)
- RIGHT JOIN (WHERE … IS NULL ile kullanılırsa fark işlemi)
- FULL OUTER JOIN (Kümelerde birleşim işlemi)
JOIN çeşitlerinin daha anlaşılır anlatılabilmesi için kümelerin şematik gösterimi oldukça faydalıdır. Bu sebeple her bir veritabanı tablosu, bir küme olarak gösterilecektir.
Örneklerin daha iyi anlaşılabilmesi için aşağıdaki komutlar ile tablo ve verileri veritabanınıza kaydedebilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | CREATE TABLE kulup ( kulup_no INT IDENTITY(1,1) PRIMARY KEY, kulup_ad VARCHAR(30) NOT NULL UNIQUE ); CREATE TABLE ogrenci ( ogrenci_no INT IDENTITY(1,1) PRIMARY KEY, ad VARCHAR(20) NOT NULL, kulup_no INT REFERENCES kulup(kulup_no) ); INSERT INTO kulup VALUES ('BİLİŞİM'),('FOTOĞRAFÇILIK'),('KÜTÜPHANECİLİK'); INSERT INTO ogrenci VALUES ('AHMET',1), ('BURAK',1), ('CEYDA',2), ('DEMET',2), ('EVRİM',NULL) |
Dikkat edilirse EVRİM isimli öğrenci hiçbir kulübe henüz üye olmamıştır ve KÜTÜPHANECİLİK kulübüne üye hiçbir öğrenci bulunmamaktadır. Aşağıdaki örnekler, bu senaryodaki nüans gözetilerek yapılmıştır.
INNER JOIN
INNER JOIN, kümelerde KESİŞİM işlemine denk gelmektedir. Görselden de anlaşılacağı gibi, ogrenci ve kulup tablolarındaki eşleşen kayıtlar getirilir. Hiçbir kulüpte olmayan öğrenciler (EVRİM) ile hiçbir öğrencinin olmadığı kulüpler (KÜTÜPHANECİLİK) burada gösterilmez.
1 | SELECT * FROM ogrenci INNER JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no |
LEFT JOIN
Soldaki tablonun tüm kayıtları esas alınmakta ve sağdaki tabloda eşleşen kayıtlar varsa yanlarında gösterilmektedir. Yani birleştirme işlemi soldaki tablo üzerinde yapılmaktadır.
1 | SELECT * FROM ogrenci LEFT JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no |
Burada EVRİM isimli öğrencinin hiçbir kulüpte olmadığı görülmekteyken diğer tüm öğrenciler ve üye oldukları kulüpler karşılarında yazmaktadır.
LEFT JOIN – IS NULL
Hiçbir kulübe üye olmayan öğrencileri merak ediyorsak LEFT JOIN ile birlikte, sağdaki tablonun (kulup) ortak alanı IS NULL ifadesiyle sınanarak sorgu yazılır. Bu sorgu ile kümelerde O\K (O fark K) işlemi gerçekleştirilir.
1 | SELECT * FROM ogrenci LEFT JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no WHERE kulup.kulup_no IS NULL |
Bu durumda hiçbir kulübe üye olmayan EVRİM karşımıza getirilirken diğer öğrenciler gösterilmez.
RIGHT JOIN
RIGHT JOIN ile sağdaki tablo üzerindeki tüm kayıtlar esas alınarak işlem yapılır. Dolayısıyla birleştirme işlemi bu sefer sağdaki tablo üzerinde yapılacaktır.
1 | SELECT * FROM ogrenci RIGHT JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no |
Bu sorgu ile tüm kulüpleri ve bunlara üye olan öğrenciler gösterilmektedir. Dikkat edilirse KÜTÜPHANECİLİK kulübüne üye olan herhangi bir öğrenci bilgisi yoktur ve hatta EVRİM isimli öğrenci hiç gösterilmemiştir.
RIGHT JOIN – IS NULL
Eğer hiçbir kişinin üye olmadığı kulüpleri merak ediyorsak RIGHT JOIN ile kulup tablosunu işaret ederiz ve soldaki tablonun ortak alanını (kulup_no) IS NULL ile sınayabiliriz. Bu sorgu ile kümelerde K\O (K fark O) işlemi gerçekleştirilir.
1 2 | SELECT * FROM ogrenci RIGHT JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no WHERE ogrenci.kulup_no IS NULL |
Yukarıdaki sorgu sonucunda karşımıza yalnızca KÜTÜPHANECİLİK kulübü getirilecektir.
FULL OUTER JOIN
FULL OUTER JOIN ifadesinin küme işlemlerinde karşılığı BİRLEŞİM işlemidir. Yani hem sağdaki kümenin hem de soldaki kümenin tüm kayıtları karşımıza getirilecektir.
1 | SELECT * FROM ogrenci FULL OUTER JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no |
Dikkat edilirse hem EVRİM isimli öğrenciyi hem de KÜTÜPHANECİLİK kulübünü aynı anda görebilmekteyiz ancak bunlarla eşleşen kayıtlar olmadığı için karşılarında NULL ifadeleri yer almaktadır.
FULL OUTER JOIN – IS NULL – OR
FULL OUTER JOIN kümelerde BİRLEŞİM işlemine karşılık gelirken aşağıda yazılan komut ile (O\K) ile (K\O) kümelerinin BİRLEŞİM işlemi gerçekleştirilmiş olur.
1 2 | SELECT * FROM ogrenci FULL OUTER JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no WHERE ogrenci.kulup_no IS NULL OR kulup.kulup_no IS NULL |
Dolayısıyla bu sorgu sonucunda hiçbir kulüpte olmayan EVRİM ile kimsenin üye olmadığı KÜTÜPHANECİLİK kulübü karşımıza gelmektedir.
NOT: JOIN işlemlerinde LEFT ve RIGHT ifadesi, doğrudan soldaki veya sağdaki tablo anlamında kullanılmaktadır. Dolayısıyla tabloların yerlerinin değiştirilmesiyle LEFT JOIN ifadesinin RIGHT JOIN ile değiştirilmesi bize aynı sonucu verecektir. Aşağıdaki iki sorgunun da sonucu aynıdır. Ancak bu yazı içerisinde anlam karmaşası olmaması için ogrenci tablosu her zaman solda, kulup tablosu da her zaman sağda gösterilmiştir.
1 2 | SELECT * FROM ogrenci LEFT JOIN kulup ON ogrenci.kulup_no=kulup.kulup_no; SELECT * FROM kulup RIGHT JOIN ogrenci ON ogrenci.kulup_no=kulup.kulup_no; |
Sayın Hocam, son sorguda INNER JOIN yapılmış RIGHT JOIN yerine.
Bilginize…
Teşekkür ederim. Düzeltildi.