Sorgularda INNER JOIN – Bölüm 12

Bu bölümde kullanılan en yaygın join sorgu türü olan INNER JOIN sorgularının nasıl yazıldığını öğreneceksiniz. Tablolar arasındaki mantıksal ilişkiyi belirterek her tabloda eşleşen özniteliklere sahip satırları çekeceksiniz.

INNER JOIN

Inner join kullanan T-SQL sorguları, özellikle yüksek oranda normalize edilmiş veri tabanı ortamlarında, birçok işletme problemini çözmek için en yaygın sorgu türüdür. Birden fazla tabloda depolanan verileri almak için, genellikle inner join sorguları kullanarak tabloları birleştirmeniz gerekir. Bildiğiniz gibi inner join, mantıksal işlem aşamasına bir Kartezyen ürün olarak başlar, daha sonra predicate ile eşleşmeyen satırları kaldırmak için filtreleme işlemi uygulanır.

SQL-89 syntax’ında, bu predicate WHERE deyiminde; SQL-92 syntax’ında ise ON ifadesinin hemen yanındadır:

--ANSI SQL-89 syntax
SELECT c.companyname, o.orderdate
FROM Sales.Customers AS c, Sales.Orders AS o
WHERE c.custid = o.custid;
--ANSI SQL-92 syntax
SELECT c.companyname, o.orderdate
FROM Sales.Customers AS c JOIN Sales.Orders AS o
ON c.custid = o.custid;

SQL Server sorgu optimizer’ı, bir syntax’ı diğerine tercih ederken performansı hesaba katarak yapmaz. Bununla birlikte, özellikle outer join gibi join işlemleri hakkında bilgi edindiğiniz zaman SQL-92 syntax’ında bulunan ON deyimiyle filtreleme işlevini tercih edeceğinize karar vereceksiniz. Join filtresinin predicate’ini ON ifadesinde tutmak ve WHERE ifadesinde diğer filtreleri yerleştirmek sorgularınızın okunuşunu ve test edilmesini kolaylaştıracak.

SQL Server’ın ANSI SQL-92 syntax’ını kullanarak bu sorgunun mantıksal olarak işleyeceği adımları inceleyelim. Anlaşılabilirlik için satır numaraları eklenmiştir:

ANSI-92 Join
1) SELECT c.companyname, o.orderdate
2) FROM Sales.Customers AS c
3) JOIN Sales.Orders AS o
4) ON c.custid = o.custid;

Daha önce öğrendiğimiz üzere, FROM ifadesi SELECT ifadesinden önce işlenir. 2. satırdan başlayarak işlemi izleyelim:

  • FROM ifadesi, Sales.Customers tablosunu input olarak belirler ve “c” takma adını verir.
  • 3. satırdaki JOIN operatörü bir INNER join varsayılan kullanımını belirtir ve Sales.Orders öğesine de takma ad olarak “o” verir ve ikinci input tablo olarak belirler.
  • SQL Server bu tablolarda mantıksal bir Kartezyen birleşimi gerçekleştirir ve sonuçları sanal tablo şeklinde bir sonraki aşamaya geçirir. (Optimizer kararlarına bağlı olarak sorgunun fiziksel işlenişi, Kartezyen ürün işlemi gibi gerçekleştirilmeyebilir.)
  • SQL Server, yalnızca “c” tablosundaki custID değerinin “o” tablosundaki custID ile eşleşen satırları koruyarak ON ifadesini kullanarak sanal tabloyu filtreler.
  • SQL Server, sanal tabloyu ON ifadesindeki mantığı kullanarak filtreleme işleminde eşleşen satırları alır.
  • Kalan satırlar sanal tabloda bırakılır ve SELECT ifadesinde bir sonraki aşamaya verilir. Örnekte sanal tablo daha sonra SELECT ifadesi tarafından işlenir ve yalnızca iki sütun döndürülür.
  • Dönen sonuç ise sipariş vermiş olan müşterilerin listesi olarak karşımıza çıkar. Daha önce sipariş vermeyen müşteriler, müşteri listesindeki bir değere karşılık gelmeyen bir müşteri kimliğine sahip olan tüm siparişler gibi ON maddesi tarafından filtrelenmiştir.
Inner Join Syntax

Inner join kullanılan sorgular yazarken aşağıdakileri dikkate almakta fayda var:

  • Görüldüğü üzere tablo takma adları, sadece SELECT için değil, ayrıca ON deyimini ifade etmek için de tercih edilmektedir.
  • Inner join’ler, orderID gibi tek bir eşleşme niteliğinde ya da orderID ve productID’in kombinasyonu gibi birden fazla eşleşme niteliğinde gerçekleştirilebilir. Birden çok özellik ile eşleşen birleşimlere bileşik join’ler adı verilir.
  • FROM deyimindeki tabloların listelenip birleştirildiği sıralamanın SQL Server optimizer’ı için önemi yoktur. (Bir sonraki yazıda anlatacağımız OUTER JOIN sorguları için bu geçerli değildir.) Kavramsal olarak, join’ler soldan sağa değerlendirilir.
  • JOIN sözcüğünü FROM listesindeki her iki tablo için bir kez; üç tablo olursa iki kez kullanın.
Inner Join Örnekleri

Aşağıda bazı inner join örnekleri verilmiştir.

Bu sorguda Production.Categories tablosundaki categoryID ile “Production.Products” tablosundaki categoryID sütunlarını kullanarak join uygulanmıştır:

SELECT c.categoryid, c.categoryname,
p.productid, p.productname
FROM Production.Categories AS c
JOIN Production.Products AS p
ON c.categoryid = p.categoryid;

Bu sorguda ise Sales.Customers’dan HR.Employees’a şehir ve ülke özellikleriyle ilgili iki öznitelik (sütun) kullanarak bileşik join işlemi gerçekleştirir. DISTINCT operatörü ile yinelenen şehir ve ülke değerleri kaldırılır:

SELECT DISTINCT e.city, e.country
FROM Sales.Customers AS c
JOIN HR.Employees AS e
ON c.city = e.city AND c.country = e.country;

Sonraki örnekte ise inner join’in üç tablo ile kullanımı gösterilmektedir. Sales.OrderDetails tablosunun Sales.Orders tablosuna değil JOIN’in Sales.Customers ve Sales.Orders arasındaki çıktısına eklendiğini görüyorsunuz. JOIN … ON’un her biri kendi sanal tablosunun filtrelemesini gerçekleştirir. SQL Server sorgu optimizer’ı, join ve filtrelemenin gerçekleştirileceği sırayı belirlemektedir.

SELECT c.custid, c.companyname, o.orderid, o.orderdate, od.productid, od.qty
FROM Sales.Customers AS c
JOIN Sales.Orders AS o
ON c.custid = o.custid
JOIN Sales.OrderDetails AS od
ON o.orderid = od.orderid;

Leave a Reply

Your email address will not be published. Required fields are marked *