16 Ocak 2017 Pazartesi

HAVING




Belli bir guruba yönelik sorgular yazılırken gruplandırarak kümeleme fonksiyonlarından yaralanılır.
HAVING deyimi sorguda bir koşul belirtilmesi gerekirse kullanılmaktadır. Daha önceki slayttan hatırlayacağınız gibi gruplandırma işlemini gerçekleştirmek için GROUP BY fonksiyonunu kullanmıştık.
GROUP BY fonksiyonunda bir koşula ihtiyaç var ise HAVING deyimi kullanılmaktadır.

HAVING deyiminin genel kullanım biçimi aşağıdaki gibidir.
SELECT Alan_Adları
     FROM Tablo/Tablolar
          [WHERE Şart/Şartlar]
                  [GROUP BY Sütunlar]
                           [HAVING Grup_Kısıtlaması]

HAVING deyimi, GROUP BY fonksiyonu olmadan kullanılamaz.


HAVING deyiminin ardından SUM, COUNT, MAX, MIN ve AVG gibi fonksiyonlar gelmelidir. Çünkü HAVING deyimi sadece gruplanmış veriler üzerindeki işlemlerde geçerlidir.
WHERE komutu ise, tablonun tek satırı üzerinde işlem yapıldığında kullanılabilmektedir. Bazı durumlarda bir SQL sorgusunda WHERE ve HAVING deyimleri birlikte kullanılabilmektedir.


HAVING deyiminin kullanımına bir örnek verelim.
Sipariş detayları tablosunda 1 den fazla sipariş edilen ürünlerin, ürün numaraları ve sayısını gösteren SQL ifadesi şöyle olacaktır:
SELECT urunID, COUNT (*) AS 'Sipariş Sayısı'
      FROM siparisDetay
             GROUP BY urunID
                      HAVING COUNT(*) > 1



Bu sorgu, öncelikle siparisDetay tablosunun urunID’lerine göre gruplandırır. Daha sonra gruplamış olduğu bu urunID’lerini COUNT(*) fonksiyonunu kullanarak sayar. Eğer 1’den büyük ise 'urunID' ve verilen sipariş sayısını kullanıcıya gösterir.



Başka bir örnek verelim. Bu örneğimizde birden fazla tablo kullanılacaktır.
Toplam sipariş tutarı 100 TL’ nin üzerinde olan müşterilerin vermiş oldukları toplam sipariş sayısını, müşteri numaralarını ve toplam sipariş tutarlarını görüntüleyen SQL ifadesi şöyle olacaktır:
SELECT musteriID, COUNT (*) AS 'Toplam Sipariş Sayısı',
                 SUM (siparisDetay.birimFiyat*siparisDetay.miktar)
                 AS 'Toplam Sipariş Tutarı'
FROM siparisler  INNER JOIN siparisDetay
             ON siparisler.siparisID = siparisDetay.siparisID
GROUP BY siparisler.musteriID
HAVING SUM (siparisDetay.birimFiyat*siparisDetay.miktar) > 100


Ortalama sipariş tutarı 50 TL nin üzerinde olan tüm müşterilerin vermiş oldukları toplam sipariş sayısı, toplam sipariş tutarı ve ortalama sipariş tutarını gösteren SQL ifadesi şöyle olacaktır.
   
SELECT musteriID, COUNT(*) AS 'Toplam Sipariş Sayısı',
                 SUM (siparisDetay.birimFiyat*siparisDetay.miktar)
                 AS 'Toplam Sipariş Tutarı',
                 AVG (siparisDetay.birimFiyat*siparisDetay.miktar)
                 AS 'Ortalama Sipariş Tutarı'
FROM siparisler INNER JOIN siparisDetay ON
              siparisler.siparisID = siparisDetay.siparisID
GROUP BY siparisler.musteriID
HAVING AVG (siparisDetay.birimFiyat*siparisDetay.miktar) > 50

NOT: Bu sorgular yazılırken satici veritabanında Siparişler ve Sipariş Detayları tablolarını kullanınız.


Bu sorguda “siparisler” ve “siparişDetay” tabloları birleştirilerek, müsteriID’lerine göre gruplanmıştır. Daha sonra HAVING kısmında AVG ile ortalama sipariş tutarları hesaplanarak 50 TL den büyük ise listelenmesi sağlanmıştır.

HAVING ve diğer gruplama fonksiyonlarının kullanımına dikkat etmek gerekir. Grup koşulları WHERE ifadesi ile birlikte kullanılamazlar.
Örneğin bir bölüm bazında yapılacak olan bir işlemde bölümdeki personelin ücret ortalaması 1000 TL den büyük olanları listelemek istersek aşağıdaki kullanım yanlış olacaktır.

SELECT bolumNo, AVG(ucret)
     FROM personel
           WHERE AVG(ucret) > 1000
                  GROUP BY bolumNo


Bu SQL cümlesi istenildiği gibi çalışmayacaktır. Çünkü grup koşulları WHERE ifadesi ile birlikte çalışmazlar. Bunun doğru kullanımı şöyle olacaktır.

SELECT bolumNo, AVG(ucret)
         FROM personel
           GROUP BY bolumNo
                  HAVING AVG(ucret) > 1000