GROUP BY ve Toplama Fonksiyonları

Bir önceki derste birden fazla tabloyu JOIN ile birleştirmeyi öğrenmiştik. Artık elimizde geniş bir veri tablosu olduğuna göre, sırada bu veriyi tek tek satır satır okumak yerine özetlemek var. Bu derste GROUP BY komutunu ve COUNT, SUM, AVG, MIN, MAX gibi toplama (aggregate) fonksiyonlarını kullanarak ilk basit raporumuzu çıkaracağız. Bir sonraki derste ise bu grupları HAVING ile filtrelemeyi göreceğiz; bu yüzden burada öğrendikleriniz doğrudan ona zemin hazırlıyor.

Bu derste ne yapacağız?

Hedefimiz, ham verideki yüzlerce satırı anlamlı özetlere dönüştürmek. Örneğin "Her şehirden kaç sipariş geldi?" ya da "Her müşterinin toplam harcaması ne kadar?" gibi soruların cevabını tek bir sorguyla almayı öğreneceğiz. Ön koşul olarak SELECT ve WHERE komutlarını bilmeniz, tablo ve sütun kavramına aşina olmanız yeterli. JOIN bilmeniz zorunlu değil ama faydalı olur, çünkü ileride birden çok tablodan gelen veriyi de gruplayabileceksiniz. Bu ders yaklaşık 13 dakika sürer.

Kavram

GROUP BY'ı bir sınıftaki öğrencileri şubelerine göre gruplamaya benzetebiliriz. Diyelim ki 90 öğrenci var ve her biri A, B veya C şubesinde. "Her şubede kaç öğrenci var?" diye sormak istediğinizde, öğrencileri tek tek saymak yerine önce onları şubelerine göre kümelere ayırır, sonra her kümenin büyüklüğüne bakarsınız. İşte GROUP BY tam olarak bunu yapar: belirttiğiniz bir sütuna göre satırları kümelere ayırır.

Ancak kümelere ayırmak tek başına yeterli değildir; her kümeyle ilgili bir özet sayı üretmek gerekir. Burada devreye toplama fonksiyonları girer:

  • COUNT: Bir kümede kaç satır olduğunu sayar. "Her şehirden kaç sipariş var?" sorusunun cevabı budur.
  • SUM: Bir sütundaki sayıları toplar. "Her şehirden toplam ne kadar tutar sipariş edilmiş?" sorusuna cevap verir.
  • AVG: Ortalamayı hesaplar. "Her şehirdeki ortalama sipariş tutarı nedir?" sorusunu yanıtlar.
  • MIN ve MAX: Bir kümedeki en küçük ve en büyük değeri bulur. "En düşük ve en yüksek sipariş tutarı ne kadar?" gibi sorularda kullanılır.

Günlük hayattan bir benzetme daha yapalım: Bir market zincirinin muhasebecisi her şubenin günlük satışını tek tek fişlerden toplamak yerine, şubeleri gruplayıp her grubun toplamını görmek ister. GROUP BY ve toplama fonksiyonları, veritabanına "bana tek tek fişleri değil, şube başına özetini göster" demenizi sağlar.

Adım adım uygulama

Örneğimizde Siparisler adında bir tablomuz olduğunu varsayalım. Bu tabloda şu sütunlar bulunuyor: SiparisID, MusteriAdi, Sehir, Tutar. Şimdi adım adım ilerteyelim.

  • 1. Adım — En basit gruplama: Her şehirden kaç sipariş geldiğini öğrenmek istiyoruz. Sorgu düzenleyicinize şunu yazın: SELECT Sehir, COUNT(*) AS SiparisSayisi FROM Siparisler GROUP BY Sehir; Burada SELECT Sehir ifadesi hangi sütuna göre gruplama yapacağımızı gösterir, COUNT(*) her grupta kaç satır olduğunu sayar, AS SiparisSayisi bu sayıya okunaklı bir isim verir, GROUP BY Sehir ise satırları Sehir sütununa göre kümelere ayırır.
  • 2. Adım — Toplam tutar hesaplama: Şimdi her şehirden ne kadar toplam gelir elde edildiğini bulalım: SELECT Sehir, SUM(Tutar) AS ToplamTutar FROM Siparisler GROUP BY Sehir; Bu sorguda SUM(Tutar) her şehir grubundaki Tutar sütununu toplar.
  • 3. Adım — Ortalama hesaplama: Her şehirdeki ortalama sipariş tutarını görmek için: SELECT Sehir, AVG(Tutar) AS OrtalamaTutar FROM Siparisler GROUP BY Sehir; AVG(Tutar), ilgili grubun ortalamasını hesaplar.
  • 4. Adım — Birden fazla fonksiyonu birlikte kullanma: Tek bir sorguda hem sayı hem toplam hem ortalama görmek mümkündür: SELECT Sehir, COUNT(*) AS SiparisSayisi, SUM(Tutar) AS ToplamTutar, AVG(Tutar) AS OrtalamaTutar FROM Siparisler GROUP BY Sehir; Bu, bir raporun temel iskeletidir ve gerçek hayatta çokça kullanılır.
  • 5. Adım — En düşük ve en yüksek değeri bulma: Her şehirdeki en küçük ve en büyük siparişi görmek için: SELECT Sehir, MIN(Tutar) AS EnDusukTutar, MAX(Tutar) AS EnYuksekTutar FROM Siparisler GROUP BY Sehir;
  • 6. Adım — WHERE ile GROUP BY'ı birlikte kullanma: Gruplamadan önce satırları filtrelemek isterseniz WHERE, GROUP BY'dan önce yazılır: SELECT Sehir, COUNT(*) AS SiparisSayisi FROM Siparisler WHERE Tutar > 100 GROUP BY Sehir; Burada önce yalnızca tutarı 100'den büyük siparişler seçilir, ardından bu seçilmiş satırlar şehre göre gruplanır. Yani sıralama her zaman şöyledir: önce WHERE ile satırlar süzülür, sonra GROUP BY ile kümelenir.
  • 7. Adım — Sonucu sıralama: Raporu en çok siparişten en aza doğru sıralamak isterseniz ORDER BY'ı en sona ekleyin: SELECT Sehir, COUNT(*) AS SiparisSayisi FROM Siparisler GROUP BY Sehir ORDER BY SiparisSayisi DESC; Bu sayede raporunuzun en üstünde en yoğun şehir görünür.

Kullandığınız veritabanı programının arayüzü (sorgu penceresi, çalıştır düğmesi, sonuç sekmesi gibi öğelerin yeri) sürüme ve programa göre değişebilir; burada anlatılan mantık ise SQL dilinin kendisine ait olduğu için hangi programı kullanırsanız kullanın aynı şekilde geçerlidir.

Sık karşılaşılan sorunlar

Hata veya BelirtiOlası NedenÇözüm
"Column is not in GROUP BY" veya benzeri hataSELECT içinde toplama fonksiyonuna girmeyen bir sütun var ama bu sütun GROUP BY listesinde yokSELECT ile listelediğiniz her sütunu (toplama fonksiyonu içinde olmayanları) GROUP BY ifadesine de ekleyin
Tüm tablo tek bir satırda özetleniyor, beklediğim gruplar çıkmıyorGROUP BY ifadesi yazılmamış, sadece COUNT veya SUM kullanılmışHangi sütuna göre gruplamak istediğinizi belirtip GROUP BY [sütun adı] ekleyin
Sonuçlar beklediğimden farklı, bazı satırlar eksik görünüyorWHERE ile gruplamadan önce satırlar yanlışlıkla filtrelenmiş olabilirWHERE koşulunu tekrar kontrol edin; sadece gruplama sonrası filtreleme gerekiyorsa bir sonraki derste göreceğimiz HAVING kullanılmalı
AVG veya SUM sonucu boş (NULL) çıkıyorİlgili sütunda NULL değerler var ya da sütun metin türünde, sayısal değilSütunun sayısal bir veri tipinde olduğundan emin olun; NULL satırları toplama fonksiyonları otomatik olarak yok sayar, bu normaldir
COUNT(*) ile COUNT(sütun adı) farklı sonuç veriyorCOUNT(*) tüm satırları sayar, COUNT(sütun adı) ise o sütunda NULL olmayan satırları sayarAmacınıza göre doğru olanı seçin: toplam satır sayısı için COUNT(*), belirli bir sütunun dolu olduğu satır sayısı için COUNT(sütun adı)

Mini görev

Şimdi sıra sizde. Elinizdeki (veya örnek olarak oluşturduğunuz) Siparisler tablosunu kullanarak aşağıdaki üç raporu tek tek yazın ve çalıştırın:

  • Her müşterinin toplam kaç sipariş verdiğini gösteren bir sorgu (MusteriAdi sütununa göre grupla, COUNT kullan).
  • Her müşterinin toplam ne kadar harcadığını gösteren bir sorgu (MusteriAdi sütununa göre grupla, SUM kullan).
  • Sadece tutarı 50'den büyük siparişleri dikkate alarak, her şehrin ortalama sipariş tutarını gösteren bir sorgu (WHERE ve GROUP BY'ı birlikte kullan, AVG kullan).

Kontrol listesi:

  • Her sorguda GROUP BY, gruplamak istediğiniz sütunu içeriyor mu?
  • SELECT içindeki toplama fonksiyonuna girmeyen her sütun, GROUP BY listesinde de var mı?
  • WHERE ifadesi GROUP BY'dan önce mi yazıldı?
  • Sonuç sütunlarına AS ile anlamlı isimler verdiniz mi?
  • Sonuçları gözden geçirip mantıklı olup olmadığını kontrol ettiniz mi (örneğin toplam tutarlar negatif çıkmamalı)?

Kendini sına

1. GROUP BY komutunun temel görevi nedir?

2. COUNT(*) ile COUNT(SutunAdi) arasındaki fark nedir?

3. Bir sorguda hem WHERE hem GROUP BY kullanılacaksa, hangisi önce yazılır?

4. SELECT ifadesinde bir sütun toplama fonksiyonu içinde değilse, bu sütunla ilgili ne yapılmalıdır?

5. Her şehirdeki en yüksek sipariş tutarını bulmak için hangi fonksiyon kullanılır?

Cevaplar

  • 1. Satırları belirtilen bir veya birden fazla sütuna göre kümelere ayırıp, her küme için ayrı bir özet satırı oluşturur.
  • 2. COUNT(*) tablodaki tüm satırları sayar; COUNT(SutunAdi) ise yalnızca o sütunda NULL olmayan (dolu) satırları sayar.
  • 3. WHERE, GROUP BY'dan önce yazılır; çünkü önce satırlar filtrelenir, sonra filtrelenmiş satırlar gruplanır.
  • 4. Bu sütun mutlaka GROUP BY ifadesine de eklenmelidir, aksi halde veritabanı hata verir.
  • 5. MAX fonksiyonu kullanılır, örneğin MAX(Tutar).

Bu dersi kayıt olmadan izleyebilirsin. İlerlemeni kaydetmek, sertifika almak ve puan tablosuna girmek için ücretsiz üye ol: Kayıt Ol