PM uzerinden bir arkadaş database JOIN işlemi hakkında bir soru sorduğu icin ufak bir rehber hazırlamak istedim. JOIN işlemleri genelde yeni başlayan arkadaşların bilmediği bir husus olduğundan, 1 sorguda yapılabilecek işlemler, onlarca sorguda yapılacak şekilde kodlanmakta ve verimsiz calıştırılmaktadır. Bu yazıda bu konuya biraz ışık tutmaya calışacağım.

JOIN nedir?
------------

Join (birleştir, eşleştir) bir veritabanında iki veya daha fazla veritabanı tablosunu ortak bir paydada bir araya getirmek amacıyla kullanılan SQL sorgu işlemidir. Orneğin bir tablonuzda urunleriniz var, genel bazı bilgiler urun adı diyelim. Diğer bir tablonuzda ise urunler kategorilere atanmış olsun. Belirli bir kategorideki urunleri listelemek istediğinizde, once kategori tablosundan isim, sonra kategori X urun tablosundan eşleşme, ve urun tablosundan isim yapmanız icin 3 sorgu yapmaya ihtiyacınız var. Boyle durumlarda JOIN işlemi bunu tek sorguda yapabilmenizi sağlar.

INNER JOIN
-------------

JOIN tiplerinden bir tanesi INNER JOIN'dir. Farkını ornekle acıklamak daha yararlı olur. Yukarıdaki durumdaki tabloların aşağıdaki şekilde olduğunu varsayalım

Tablo=URUN
urun_id (serial)
urun_ismi (text)
urun_fiyat (float)

Tablo=KATEGORI
kat_id (serial)
kat_ismi (text)

TABLO=KATURUN
ku_id (serial)
kat_id (int) -> Kategori tablosuna baglar
urun_id (int) -> Urun tablosuna baglar.

Elimizde POST veya GET ile gelmiş bir $kat_id değişkeni olduğunu duşunelim. Kategori ID'si olarak.

Kategori ismini al.
-> SELECT kat_ismi FROM kategori WHERE kat_id='$kat_id'

Kategorideki urumleri al
-> SELECT urun_id FROM katurun WHERE kat_id='$kat_id'

Yukarıdan aldığın urun_id ile urunlerin bilgilerini al
-> SELECT urun_ismi, urun_fiyat FROM urun WHERE urun_id='$urun_id'

3. adımı while'a alacağınız icin yuzlerce sorgu anlamına gelebilir bu.

Bunun yerine JOIN kullanmak istersek

Kod:
SELECT k.kat_ismi, u.urun_ismi,u.urun_fiyat FROM urun AS u INNER JOIN katurun AS ku ON ku.urun_id=u.urun_id INNER JOIN kategori AS k ON k=kat_id=ku.kat_id WHERE ku.kat_id='$kat_id'

Turkce mealine gelirsek bunun, oncelikli olarak gorduğunuz AS 'x' ifadeleri bağladığınız tablolara kısa isim vermek icin kullanılmaktadır. urun tablosunu u, katurun tablosunu ku, kategori tablosunu k olarak adlandırdık. Dolayısıyla bu tablolardan cekmek istediğimi verileri referans olarak k.kat_id, u.urun_fiyat gibi adlandırmamız lazım. Sadece kat_id derseniz kullandığınız database ve versiyona gore, size "ambigious" muallak hatası verebilir. Cunku kat_id birden cok tabloda bulunan bir eleman, hangisini referans aldığını bilmiyor database.

Dolayısıyla birinci satırda u tablosundan isim ve fiyatı cekmek isteyeceğimizi bildirdik. İkinci satırda katurun tablosunu urun tablosuna birleştirelim istedik.

ON x=y şeklindeki ifadede birleştirme koşulunu tanımlıyoruz. URUN_ID sinde birleştirme yapalım. Urun tablosundaki urun_id, katurun tablosundaki urun_id elemanına eşit olduğu alanlarda birleştirme yapalım istedik. İkinci satırda da bunu kategori tablosuna kat_id elemanı uzerinden birleştirdik. Son olarak da WHERE ile bu 3 tablo uzerinde istediğimiz filtrelemeyi uyguladık.

Ornek veriler şoyle ise;

Urun
-----
1 - Mutfak robotu - 150.00
2 - Cim bicme makinesi - 450.00
3 - Bicak seti - 75.00
4 - catal bicak takimi - 109.00
5 - samsung cep telefonu - 400.00

Kategori
--------
1 - Mutfak esyalari
2 - Bahce esyalari

Kat urun
--------
1 - 1 (kat x urun)
1 - 3
1 - 4
2 - 2
3 - 5

Kod:
SELECT k.kat_ismi, u.urun_ismi,u.urun_fiyat FROM urun AS u INNER JOIN katurun AS ku ON ku.urun_id=u.urun_id INNER JOIN kategori AS k ON k=kat_id=ku.kat_id WHERE ku.kat_id='$kat_id'

kat_id = 1 olduğunda

Mutfak esyalari - Mutfak robotu - 150.00
Mutfak esyalari - Bicak seti - 75.00
Mutfak esyalari - catal bicak takimi - 109.00

kat_id = 2 olduğunda
Bahce esyalari - Cim bicme makinesi - 450.00

Verecektir.


INNER JOIN işleminde bağlama koşulu (ON x=y) gercekleşmediğinde, o satır sonucta gozukmez.

kat_id=3 olduğunda sıfır sonuc doner, cunku INNER JOIN bağlanan kategori tablosunda kat_id=3 gercekleyen bir row yok.


OUTER JOIN
--------------
OUTER JOIN işleminde ise bağlama koşulu gercekleşmese bile o satırlar dondurulur, bağlanamayan tablodan veri cekiliyorsa lisanssız olarak ceker. Aynı ornekte kat_id=3 icin kategori tablosunda bir veri olmadığında belirtmiştik. INNER değil OUTER JOIN kullandığımızda şoyle bi manzara olur.

Kod:
SELECT k.kat_ismi, u.urun_ismi,u.urun_fiyat FROM urun AS u INNER JOIN katurun AS ku ON ku.urun_id=u.urun_id LEFT OUTER JOIN kategori AS k ON k=kat_id=ku.kat_id WHERE ku.kat_id='$kat_id'

lisanssız - samsung cep telefonu - 400.00

kategori ismi cekilemedi cunku yok. Ama satır gene de donduruldu (LEFT sol tarafı baz alarak yani katurun tablosunu baz alarak, kat_id=3 gerceklendi)

RIGHT OUTER JOIN'de ise tam tersi sağ taraf baz alınarak gercekleme sağlanmaya calışılıp SOL taraftaki değer lisanssız dondurulebilirdi.


Konuya ilgi olursa daha gelişmiş SQL sorguları uzerine devam edebiliriz.

Link ve yazara atıfta bulunarak yayınlayabilirsiniz.