Veritabanı yönetimi ve veri analizi süreçlerinde, ham veriyi sadece listelemek çoğu zaman yeterli olmaz. Özellikle iş zekası (BI) uygulamalarında, devasa veri kümelerinden anlamlı özetler ve raporlar çıkarmak için verileri belirli kategorilere göre gruplandırmanız ve bu gruplar üzerinde matematiksel hesaplamalar yapmanız gerekir. SQL’de bu tür özet raporlamaların ve veri kümeleme işlemlerinin kalbinde GROUP BY ve HAVING tümceleri yer alır.
1. Hazırlık: SQL Toplama (Aggregate) Fonksiyonları Nelerdir?
GROUP BY ve HAVING komutlarının mantığını tam olarak kavrayabilmek için, öncelikle SQL’in toplama fonksiyonlarını bilmek gerekir. Bu fonksiyonlar, bir sütundaki birden fazla satırı (veya grubu) alarak tek bir özet değer döndürürler. En sık kullanılan toplama fonksiyonları şunlardır:
- SUM(): Sayısal bir sütundaki değerlerin toplamını hesaplar.
- AVG(): Sayısal bir sütundaki değerlerin aritmetik ortalamasını bulur.
- COUNT(): Bir gruptaki veya tablodaki satır sayısını hesaplar. (
COUNT(*)null değerler dahi tüm satırları sayarken,COUNT(sütun_adi)sadece null olmayan satırları sayar.) - MAX() ve MIN(): Bir sütundaki sırasıyla en büyük (maksimum) ve en küçük (minimum) değeri döndürür.
Bu fonksiyonlar, veriyi özetlemek için GROUP BY komutuyla birlikte adeta bir takım olarak çalışırlar.
2. SQL GROUP BY Komutu Nedir ve Nasıl Kullanılır?
GROUP BY tümcesi, bir veya daha fazla sütunda aynı değerlere sahip olan satırları (kayıtları) gruplandırmak için kullanılır. Genellikle SELECT sorgularında yukarıda bahsettiğimiz toplama fonksiyonları (SUM, COUNT, AVG vb.) ile birlikte kullanılarak, her bir grup için özet bir sonuç üretilmesini sağlar.
Veritabanı motoru GROUP BY komutunu çalıştırırken, belirtilen sütundaki benzersiz her bir değer için yeni bir grup oluşturur ve hesaplamaları sadece o grup içindeki satırlara uygular.
Temel GROUP BY Sözdizimi (Syntax)
Standart bir GROUP BY sorgusunun yapısı şu şekildedir:
SELECT sutun_adi1, AGGREGATE_FONKSIYONU(sutun_adi2)
FROM tablo_adi
WHERE kosul
GROUP BY sutun_adi1;
Önemli bir kural: GROUP BY tümcesi, SQL sorgusunda her zaman WHERE tümcesinden sonra, ancak ORDER BY tümcesinden önce gelmelidir.
Örneklerle GROUP BY Kullanımı
Bir e-ticaret sitenizin veritabanında Satislar adında bir tablonuz olduğunu ve her bir personelin ne kadar satış yaptığını bulmak istediğinizi varsayalım.
SELECT SaticiAdi, SUM(SatisTutari) AS ToplamSatis
FROM Satislar
GROUP BY SaticiAdi;
Bu sorguda SQL motoru, öncelikle satıcıların isimlerine göre tüm kayıtları gruplandırır. Ardından her bir isim için o isme ait SatisTutari değerlerini toplayarak ToplamSatis adlı yeni bir sütunda bize gösterir.
Birden Fazla Sütuna Göre Gruplandırma
Verilerinizi tek bir kritere göre değil, birden fazla kritere göre hiyerarşik olarak da gruplayabilirsiniz. Örneğin, departmanlara ve bu departmanlardaki şehirlere göre çalışan sayısını bulmak isterseniz:
SELECT Departman, Sehir, COUNT(*) AS CalisanSayisi
FROM Calisanlar
GROUP BY Departman, Sehir;
Bu sayede her bir departman ve o departmana ait her bir şehir kombinasyonu için alt gruplar oluşturulur ve hesaplama bu alt gruplara (sub-groups) göre yapılır.
3. SQL HAVING Tümcesi Nedir?
Gruplandırma işlemlerini öğrendik. Peki ya “Toplam satışı 50.000 TL’nin üzerinde olan satıcıları getir” demek istersek ne yapacağız? İlk akla gelen WHERE tümcesini kullanmak olabilir, ancak bu durum bir hataya yol açacaktır.
Çünkü WHERE tümcesi, veriler gruplandırılmadan önce çalışır ve tekil satırları filtreler; bu nedenle WHERE içinde SUM(), COUNT() gibi toplama fonksiyonları kullanılamaz.
İşte bu sorunu çözmek için SQL diline HAVING tümcesi eklenmiştir. HAVING, GROUP BY işlemi ile oluşturulan grupları (ve özetlenmiş verileri) filtrelemek için kullanılır.
HAVING Sözdizimi (Syntax)
HAVING tümcesi, her zaman GROUP BY tümcesinden hemen sonra yer almalıdır.
SELECT sutun_adi1, AGGREGATE_FONKSIYONU(sutun_adi2)
FROM tablo_adi
GROUP BY sutun_adi1
HAVING AGGREGATE_FONKSIYONU(sutun_adi2) > deger;
Örneklerle HAVING Kullanımı
Bir önceki satış örneğimizden devam edelim. Sadece 50.000 TL’den fazla toplam satış yapan personelleri görmek istiyorsak, sorgumuzu şu şekilde yazmalıyız:
SELECT SaticiAdi, SUM(SatisTutari) AS ToplamSatis
FROM Satislar
GROUP BY SaticiAdi
HAVING SUM(SatisTutari) > 50000;
Bu sorgu çalıştırıldığında SQL önce tüm satışları personellere göre gruplar, her birinin toplamını hesaplar. En sonda ise HAVING koşulu devreye girerek toplam satışı 50.000’den küçük veya eşit olan satıcı gruplarını sonuç listesinden (result set) tamamen çıkarır.
4. WHERE ve HAVING Arasındaki Kritik Farklar
Adayların ve yeni başlayanların en çok karıştırdığı nokta WHERE ve HAVING komutlarının ne zaman kullanılacağıdır. İkisi de bir filtreleme işlemi yapsa da çalışma zamanları ve hedefleri tamamen farklıdır:
- Hedef Kitle Farkı:
WHEREkomutu, veritabanındaki tekil satırları (kayıtları) filtreler.HAVINGiseGROUP BYile oluşturulmuş veri gruplarını filtreler. - Kullanım Zamanı Farkı: SQL’in mantıksal çalışma sırası şöyledir: Önce
WHEREile gereksiz satırlar elenir, kalan satırlarGROUP BYile gruplanır ve en sonHAVINGile istenmeyen gruplar çöpe atılır. - Toplama Fonksiyonları:
WHEREtümcesinin içinde aslaSUM,AVG,COUNTgibi fonksiyonları yazamazsınız. Bu fonksiyonların üzerinden süzme işlemi yapılacaksa zorunlu olarakHAVINGkullanılmalıdır.
Hem WHERE hem de HAVING aynı sorgu içinde gayet uyumlu bir şekilde çalışabilir. Örneğin; Sadece 2024 yılında işe girenler arasından (WHERE kısmı), toplam satışı 50.000’i aşanları (HAVING kısmı) gruplayıp listeleyebilirsiniz.
5. SQL GROUP BY ve HAVING Performans İpuçları ve Sık Yapılan Hatalar
Yüksek hacimli veri kümeleri ile (Big Data) çalışırken veya web uygulamalarınızın arka planını optimize ederken aşağıdaki ipuçlarını göz önünde bulundurmalısınız:
- Filtrelemeyi Mümkün Olduğunca Erken Yapın (WHERE Kullanın): Gruplara filtre uygulamak yerine (
HAVING), gruplamadan önce tekil satırları elemek (WHERE) performansı ciddi oranda artırır. Eğer bir filtreleme işlemi hem WHERE hem de HAVING ile yapılabiliyorsa (örneğin bir kategori ismiyle filtreleme), bunu kesinlikle WHERE ile yapmalısınız. - Toplanmamış Sütunları SELECT İçinde Bırakmayın: SQL yazarken yapılan en yaygın hatalardan biri (
ERROR 1055),SELECTlistesine yazdığınız bir sütunu,GROUP BYlistesine eklemeyi unutmaktır. MySQL ve PostgreSQL gibi sistemlerin katı ayarlarında (Strict Mode – ONLY_FULL_GROUP_BY),SELECTyan tümcesinde yer alan ve bir toplama fonksiyonunun (SUM, COUNT vb.) içinde bulunmayan her sütun, kesinlikleGROUP BYlistesinde de yer almak zorundadır. - DISTINCT ve GROUP BY Farkı: Sadece verilerinizdeki tekrar eden (duplicate) satırları kaldırmak istiyorsanız
DISTINCTkullanmak genellikle daha pratiktir. Ancak eğer verileri sadece tekilleştirmekle kalmayıp aynı zamanda hesaplama/özetleme yapacaksanızGROUP BYkullanmalısınız. - İndeksleri (Index) Kullanın: Sorgularınızı optimize etmek için
GROUP BYişlemlerinde başvurduğunuz sütunlara indeks eklemek, veritabanı motorunun büyük tabloları daha hızlı gruplamasını sağlayacaktır.
Sonuç
Web sitenizin panellerini oluştururken, müşterileriniz için detaylı satış analizleri hazırlarken ya da herhangi bir raporlama işleminde GROUP BY ve HAVING SQL komutları en önemli yardımcılarınızdır. Verileri anlamlı boyutlarda gruplayabilme (GROUP BY) ve hesaplanmış bu özetler içerisinden sadece şartları sağlayanları ayıklayabilme (HAVING) becerisi, ileri düzey veri analitiğinin (Data Analytics) temelini oluşturur.
Daha karmaşık analizler için bu komutları JOIN yapılarıyla birleştirerek birden fazla tablo üzerinden detaylı analizler geliştirmeye hemen bugün başlayabilirsiniz! Bir sonraki konumuzda görüşmek üzere.





