PM üzerinden bir arkadaş database JOIN işlemi hakkında bir soru sorduğu için 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 çalıştırılmaktadır. Bu yazıda bu konuya biraz ışık tutmaya çalış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. Örneğin bir tablonuzda ürünleriniz var, genel bazı bilgiler ürün adı diyelim. Diğer bir tablonuzda ise ürünler kategorilere atanmış olsun. Belirli bir kategorideki ürünleri listelemek istediğinizde, önce kategori tablosundan isim, sonra kategori X ürün tablosundan eşleşme, ve ürün tablosundan isim yapmanız için 3 sorgu yapmaya ihtiyacınız var. Böyle durumlarda JOIN işlemi bunu tek sorguda yapabilmenizi sağlar.
INNER JOIN
-------------
JOIN tiplerinden bir tanesi INNER JOIN'dir. Farkını örnekle açı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 düşünelim. Kategori ID'si olarak.
Kategori ismini al.
-> SELECT kat_ismi FROM kategori WHERE kat_id='$kat_id'
Kategorideki ürümleri al
-> SELECT urun_id FROM katurun WHERE kat_id='$kat_id'
Yukarıdan aldığın urun_id ile ürünlerin bilgilerini al
-> SELECT urun_ismi, urun_fiyat FROM urun WHERE urun_id='$urun_id'
3. adımı while'a alacağınız için yüzlerce sorgu anlamına gelebilir bu.
Bunun yerine JOIN kullanmak istersek
Türkçe mealine gelirsek bunun, öncelikli olarak gördüğünüz AS 'x' ifadeleri bağladığınız tablolara kısa isim vermek için kullanılmaktadır. urun tablosunu u, katurun tablosunu ku, kategori tablosunu k olarak adlandırdık. Dolayısıyla bu tablolardan çekmek 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 göre, size "ambigious" muallak hatası verebilir. Çünkü kat_id birden çok tabloda bulunan bir eleman, hangisini referans aldığını bilmiyor database.
Dolayısıyla birinci satırda u tablosundan isim ve fiyatı çekmek 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ı üzerinden birleştirdik. Son olarak da WHERE ile bu 3 tablo üzerinde istediğimiz filtrelemeyi uyguladık.
Örnek veriler şöyle 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
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) gerçekleşmediğinde, o satır sonuçta gözükmez.
kat_id=3 olduğunda sıfır sonuç döner, çünkü INNER JOIN bağlanan kategori tablosunda kat_id=3 gerçekleyen bir row yok.
OUTER JOIN
--------------
OUTER JOIN işleminde ise bağlama koşulu gerçekleşmese bile o satırlar döndürülür, bağlanamayan tablodan veri çekiliyorsa lisanssız olarak çeker. Aynı örnekte kat_id=3 için kategori tablosunda bir veri olmadığında belirtmiştik. INNER değil OUTER JOIN kullandığımızda şöyle bi manzara olur.
lisanssız - samsung cep telefonu - 400.00
kategori ismi çekilemedi çünkü yok. Ama satır gene de döndürüldü (LEFT sol tarafı baz alarak yani katurun tablosunu baz alarak, kat_id=3 gerçeklendi)
RIGHT OUTER JOIN'de ise tam tersi sağ taraf baz alınarak gerçekleme sağlanmaya çalışılıp SOL taraftaki değer lisanssız döndürülebilirdi.
Konuya ilgi olursa daha gelişmiş SQL sorguları üzerine devam edebiliriz.
Link ve yazara atıfta bulunarak yayınlayabilirsiniz.
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. Örneğin bir tablonuzda ürünleriniz var, genel bazı bilgiler ürün adı diyelim. Diğer bir tablonuzda ise ürünler kategorilere atanmış olsun. Belirli bir kategorideki ürünleri listelemek istediğinizde, önce kategori tablosundan isim, sonra kategori X ürün tablosundan eşleşme, ve ürün tablosundan isim yapmanız için 3 sorgu yapmaya ihtiyacınız var. Böyle durumlarda JOIN işlemi bunu tek sorguda yapabilmenizi sağlar.
INNER JOIN
-------------
JOIN tiplerinden bir tanesi INNER JOIN'dir. Farkını örnekle açı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 düşünelim. Kategori ID'si olarak.
Kategori ismini al.
-> SELECT kat_ismi FROM kategori WHERE kat_id='$kat_id'
Kategorideki ürümleri al
-> SELECT urun_id FROM katurun WHERE kat_id='$kat_id'
Yukarıdan aldığın urun_id ile ürünlerin bilgilerini al
-> SELECT urun_ismi, urun_fiyat FROM urun WHERE urun_id='$urun_id'
3. adımı while'a alacağınız için yüzlerce 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'
Türkçe mealine gelirsek bunun, öncelikli olarak gördüğünüz AS 'x' ifadeleri bağladığınız tablolara kısa isim vermek için kullanılmaktadır. urun tablosunu u, katurun tablosunu ku, kategori tablosunu k olarak adlandırdık. Dolayısıyla bu tablolardan çekmek 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 göre, size "ambigious" muallak hatası verebilir. Çünkü kat_id birden çok tabloda bulunan bir eleman, hangisini referans aldığını bilmiyor database.
Dolayısıyla birinci satırda u tablosundan isim ve fiyatı çekmek 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ı üzerinden birleştirdik. Son olarak da WHERE ile bu 3 tablo üzerinde istediğimiz filtrelemeyi uyguladık.
Örnek veriler şöyle 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) gerçekleşmediğinde, o satır sonuçta gözükmez.
kat_id=3 olduğunda sıfır sonuç döner, çünkü INNER JOIN bağlanan kategori tablosunda kat_id=3 gerçekleyen bir row yok.
OUTER JOIN
--------------
OUTER JOIN işleminde ise bağlama koşulu gerçekleşmese bile o satırlar döndürülür, bağlanamayan tablodan veri çekiliyorsa lisanssız olarak çeker. Aynı örnekte kat_id=3 için kategori tablosunda bir veri olmadığında belirtmiştik. INNER değil OUTER JOIN kullandığımızda şöyle 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 çekilemedi çünkü yok. Ama satır gene de döndürüldü (LEFT sol tarafı baz alarak yani katurun tablosunu baz alarak, kat_id=3 gerçeklendi)
RIGHT OUTER JOIN'de ise tam tersi sağ taraf baz alınarak gerçekleme sağlanmaya çalışılıp SOL taraftaki değer lisanssız döndürülebilirdi.
Konuya ilgi olursa daha gelişmiş SQL sorguları üzerine devam edebiliriz.
Link ve yazara atıfta bulunarak yayınlayabilirsiniz.