SQL'de SUBQUERIES (Alt Sorgular)

    • Bir Alt Sorgu başka bir SELECT, INSERT, UPDATE veya DELETE ifadesi içerisine yuvalanmış bir SELECT ifadesidir. 
    • Çoğu durumda alt sorguları JOIN ifadelerine dönüştürebilirsiniz. 
    • Alt sorgular, karmaşık sorguları biraz daha anlaşılabilir mantıksal bölümlere ayırmak için veya birbaşka sorgunun sonuç kümesine dayalı bir sorguyu çalıştırmak için kullanılır. 
    • JOIN bağlantıları Alt Sorgulardan daha hızlı işlenirler.
    • Kural olarak ise Alt Sorguları parantez içinde yazmalıyız.
    NOT : Örnek sorgulamalarda Northwind Database'i kullanacağım. bk: Nortwind Database Kurulumu 

    Sonuç Kümesinin Tablo Olarak Kullanımı : Sorguda FROM ifadesinde kullanılan tablonun yerine bir başka sorguyu kullanabilirsiniz. Sonuç Kümesine herhangi bir tabloya yapabildiğimiz gibi bir geçici takma ad verilebilir.


    SELECT T.ORDERID, T.CUSTOMERID
    FROM (SELECT ORDERID, CUSTOMERID FROM orders) AS T
     

    Sonuç Kümesinin Bir Deyim Olarak Kullanılması : SQL de bir sorguyu herhangi bir deyimin yerine kullanabilirsiniz. Bu amaç için kullanılacak bir sorgu tek bir sayısal değer veya tek bir sütun değer listesi döndürmelidir. Bir değerler listesi geri döndüren sorgular IN anahtar kelimesi içeren WHERE yantümcesi yerine kullanılabilir.
     
    Ortalamayı bulup satılan ürünlerimiz için ayrıntılı birim fiyatlarını ve bu birim fiyatlarının ortalama ürün fiyatına oranla durumunu gösterelim.
     
    SELECT ProductName AS 'ÜRÜN ADI',UnitPrice AS 'BİRİM FİYATI', UnitsInStock AS 'STOK',
    (SELECT AVG(UnitPrice) FROM Products) AS ORTALAMA,
    UnitPrice-(SELECT AVG(UnitPrice) FROM Products) AS FARK FROM Products  


    İlişkili Alt Sorgu :  İç sorgu ile dış sorgu bir alan üzerinden doğrudan bağlantılıdır.
     
    30 nolu üründen 30 dan fazla sipariş veren müşterileri listeleyelim.

    SELECT OrderID, CustomerID FROM orders AS or1
    WHERE 30<(SELECT quantity FROM [order details] AS od
    WHERE or1.OrderID=od.OrderID AND od.ProductID=30)


    Alt Sorgu-JOIN Dönüşümü :  İlişkili alt sorguları bir JOIN ifadesi yerine kullanabiliriz.
     
    İki farklı sorgu aynı sonucu vermektedir. Birinci örnekte Alt Sorgu kullanılmış, ikinci sorguda aynı sonuca JOIN ile ulaşılmıştır. 

    SELECT  DISTINCT E1.TitleOfCourtesy FROM Employees AS E1
    WHERE E1.City IN
    (SELECT E2.City FROM Employees AS E2 WHERE E1.TitleOfCourtesy<>E2.TitleOfCourtesy)


    SELECT DISTINCT E1.TitleOfCourtesy FROM Employees AS E1
    INNER JOIN Employees AS E2 WITH (NOLOCK) ON E1.City=E2.City
    WHERE E1.TitleOfCourtesy<>E2.TitleOfCourtesy
     
     
    Alt Sorgu-HAVING Dönüşümü : İlişkili bir alt sorgunun ürettiği sonuç kümesini HAVING ile de elde edebiliriz.
     
    SELECT ProductName,CategoryID,UnitPrice FROM Products AS p1
    WHERE p1.UnitPrice>(SELECT AVG(UnitPrice) FROM Products AS p2
    WHERE p1.CategoryId=p2.CAtegoryId) ORDER BY CategoryId  


    SELECT p1.ProductName,p1.CategoryID,p1.UnitPrice FROM Products AS p1
    INNER JOIN Products AS p2 WITH (NOLOCK) ON p1.CategoryID=p2.CategoryID
    GROUP BY p1.ProductName,p1.CategoryID,p1.UnitPrice
    HAVING p1.UnitPrice>AVG(p2.UnitPrice) ORDER BY p1.CategoryId
     
     
    EXISTS ve NOT EXISTS İşlevleri : Bazı durumlarda Alt Sorguların ürettikleri değerler ile değil, sorgunun sonucunun var olup olmadığıyla ilgileniriz. EXIST ve NOT EXIST işlevleri, bu sorgulamayı yapmak için kullanılır ve DOĞRU (TRUE) veya YANLIŞ (FALSE) değeri döndürür.

    Birinci sorguda ‘3/05/1998’ ve '4/05/1998' tarihleri arasında sipariş almış olan çalışanlar EXIST işlevi ile listeliyoruz. Aynı sonuca JOIN ile birleştirerekte ulaşabiliriz.
     
    SELECT EmployeeId,LastName,FirstName
    FROM Employees AS e WHERE EXISTS
    (SELECT * FROM Orders AS o
    WHERE e.EmployeeId=o.EmployeeId
    AND o.OrderDate BETWEEN '3/5/1998' AND '4/5/1998')   


    SELECT DISTINCT FirstName,LastName, e.EmployeeID
    FROM Orders AS o
    INNER JOIN Employees AS e
    ON o.EmployeeID =e.EmployeeID
    WHERE o.OrderDate BETWEEN '3/5/1998' AND '4/5/1998'