İyinet'e Hoşgeldiniz!

Türkiye'nin En Eski Webmaster Forum'una Hemen Kayıt Olun!

Kayıt Ol!

SQL'de JOIN İşlemleri

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
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

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.
 

OnurSQL

0
İyinet Üyesi
Katılım
29 Mart 2005
Mesajlar
2,025
Reaction score
1
Konum
ankara
Performans için join'i önerir misin? Özellikle MySQL'de tek tek sorgu yapmanın daha avantajlı olduğunu söyleyenler var.
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
Ortalama bir shopping cart sayfasında 50 ürün listelendiğini düşünürsen, ana sorgu, + her bir tablo için x 50 sorgudan bahsediyoruz. Resimler tablosu, eğer SEO url tablon varsa o, kategori sorgusu. Evet belki programlama kodunda 2 tane gözüküyor ama 50 adımlık while'ın içinde o. :) Bağlama koşulları doğru indekslendiği sürece, bunun performansının 150 sorgu yapmaktan daha kötü olacağını iddia etmek garip olur. Bu tarz sorgular iyi optimize edildiğinde zaten 10larca saniye sürmüyor. Öyle olduğu anlarda yanlış bir join veya gereksiz bir sorgu olduğunu hissedebilirsin zaten.

Zaten basit mantık gidersen, neden tekli basit sorgu yazmak varken insanlar 3-4 sayfa SQL sorgusu kassınlar daha iyi olmasa.
 

Türkiye’nin ilk webmaster forum sitesi iyinet.com'da forum üyeleri tarafından yapılan tüm paylaşımlardan; Türk Ceza Kanunu’nun 20. Maddesinin, 5651 Sayılı Kanununun 4. maddesinin 2. fıkrasına göre, paylaşım yapan üyeler sorumludur.

Backlink ve Tanıtım Yazısı için iletişime geçmek için Skype Adresimiz: .cid.1580508955483fe5

Üst