SQL'de Gruplama ve Özetleme: GROUP BY, Toplama Fonksiyonları ve HAVING
Beceri rehberi

SQL'de Gruplama ve Özetleme: GROUP BY, Toplama Fonksiyonları ve HAVING

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

GROUP BY, SUM, COUNT ve HAVING ile ham tabloyu rapora çevirmeyi örnek sorgularla, sık hatalar ve öğrenme yoluyla birlikte öğrenin.

GROUP BY ne yapar ve neden gerekir?

Ham bir tabloda her satır tek bir olayı anlatır: bir sipariş kalemi, bir ziyaret, bir fatura satırı. Yönetici ise olayı değil özeti ister: hangi bölgede ne kadar satış yapıldı, hangi ürün kategorisi ortalamada daha pahalı, hangi müşteri en sık sipariş veriyor. GROUP BY, satırları belirlediğiniz sütunun değerine göre kümelere ayırır; toplama fonksiyonları da her kümeyi tek satıra indirger.

Mantığı şöyle düşünün: önce tablo bölgeye göre ayrı yığınlara bölünür, sonra her yığının içinde toplam, ortalama ya da adet hesaplanır. Sonuçta yığın başına tek satır döner. GROUP BY olmadan toplama fonksiyonu tüm tabloyu tek bir yığın sayar ve tek bir satır verir.

Toplama fonksiyonları: SUM, AVG, COUNT, MIN, MAX

Gruplamanın yanında kullanılan temel fonksiyonlar bellidir. SUM bir sayısal sütunun toplamını, AVG ortalamasını, MIN ve MAX en küçük ve en büyük değerini verir. COUNT ise satır sayar ve farklı biçimlerde karşınıza çıkar: COUNT(*) kümedeki tüm satırları sayar, COUNT(sütun_adı) yalnızca o sütunda boş olmayan değerleri sayar.

Bu ayrım pratikte çok işe yarar. Sipariş tablosunda iptal tarihi sütunu yalnızca iptal edilenlerde doludur; COUNT(iptal_tarihi) size iptal edilen sipariş adedini, COUNT(*) toplam sipariş adedini verir. Toplama fonksiyonlarının hepsi boş (NULL) değerleri hesaba katmaz. Ortalama alırken boş satırların paydaya girmediğini unutmayın; yanlış yorumlanan ortalamaların sık görülen kaynağı budur.

Bir de COUNT(DISTINCT sütun_adı) vardır: tekrar edenleri bir kez sayar. Örneğin bir mağazada kaç farklı müşterinin alışveriş yaptığını bulmak için kullanılır; satır sayısıyla müşteri sayısı aynı şey değildir.

Adım adım örnek: bölge ve kategori bazında satış özeti

Elinizde satislar adlı bir tablo olsun: bolge, kategori, tutar ve siparis_no sütunları var. Bölge bazında toplam ve sipariş adedi için sorgu şöyle yazılır:

SELECT bolge, SUM(tutar) AS toplam_tutar, COUNT(*) AS siparis_adedi FROM satislar GROUP BY bolge;

Sonuçta her bölge için tek satır gelir. Kırılımı artırmak isterseniz GROUP BY listesine bir sütun daha eklersiniz: GROUP BY bolge, kategori. Artık her bölge ve kategori birleşimi ayrı bir küme olur. Yeni sütunu SELECT listesine de yazmayı unutmayın, yoksa sonucu okuyamazsınız.

Sıralama ve sınırlama bunun üzerine eklenir. En yüksek ciroyu getiren bölgeleri görmek için sonuna ORDER BY toplam_tutar DESC yazılır. Takma ad (AS) vermek raporun okunurluğunu belirgin biçimde artırır; raporu okuyan kişi SUM(tutar) ifadesi yerine toplam_tutar başlığını görür.

WHERE ile HAVING arasındaki fark

En çok karıştırılan konu budur. WHERE, gruplamadan önce çalışır ve tek tek satırları eler. HAVING ise gruplamadan sonra çalışır ve kümeleri, yani toplama sonuçlarını eler. Bu yüzden toplam tutarı belirli bir eşiğin üstünde olan bölgeleri istiyorsanız HAVING SUM(tutar) > eşik yazarsınız; WHERE içinde SUM kullanamazsınız.

İkisi aynı sorguda birlikte kullanılabilir ve genellikle kullanılmalıdır. Örneğin yalnızca belirli bir yılın siparişleriyle ilgileniyorsanız bu koşulu WHERE'e koyun: veritabanı gruplamaya daha az satırla girer, sorgu hızlanır. Toplama sonucuna bağlı koşulu ise HAVING'e bırakın.

Pratik kural: bir koşul ham satırın kendi sütununa bakıyorsa WHERE, toplama fonksiyonunun sonucuna bakıyorsa HAVING. Sorgunun mantıksal çalışma sırası FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY biçimindedir; bu sıra, takma adların neden WHERE içinde kullanılamadığını da açıklar.

Sık yapılan hatalar

En sık görülen hata, SELECT listesine gruplanmayan ve toplanmayan bir sütun yazmaktır. Satış tablosunda bölgeye göre gruplayıp yanına müşteri adını seçerseniz, veritabanı hangi müşterinin gösterileceğini bilemez ve çoğu sistem hata verir. Kural basittir: SELECT'teki her sütun ya GROUP BY listesinde olmalı ya da bir toplama fonksiyonunun içinde.

Diğer yaygın hatalar şunlardır: • JOIN ile birleştirilmiş tabloda gruplama yapıp satırların çoğalmasını fark etmemek; bir sipariş birden çok kalem satırına bağlıysa sipariş tutarı kalem sayısı kadar tekrar toplanabilir. • Tarih sütununa göre gruplarken saat bilgisini dikkate almamak; aynı gün farklı saatler ayrı küme sayılır. Önce tarihi güne ya da aya indirgeyin. • NULL değerlerin toplamları nasıl etkilediğini kontrol etmemek. • HAVING'i her koşul için kullanıp sorguyu gereksiz yavaşlatmak.

Sonucu ürettikten sonra küçük bir doğrulama alışkanlığı edinin: küme toplamlarını elle toplayıp ham tablonun genel toplamıyla karşılaştırın. Uyuşmuyorsa çoğalan satır ya da eleyen bir koşul vardır.

Başlangıçtan ileri düzeye öğrenme yolu

Önce tek tabloda tek sütunla gruplama yapın ve sonucu bir elektronik tablodaki özet tabloyla karşılaştırın; her yöntemin aynı sonucu verdiğini görmek mantığı oturtur. Ardından birden çok sütunla gruplamaya, COUNT(DISTINCT ...) kullanımına ve HAVING ile kümeleri elemeye geçin.

Sonraki aşamada tabloları JOIN ile birleştirip gruplamayı iş sorularına uygulayın: müşteri bazında ciro, ürün bazında iade oranı, ay bazında yeni müşteri adedi. Tarih fonksiyonlarıyla ay ve çeyrek kırılımı çıkarmak raporlamanın temelidir. İleri düzeyde CASE ifadesiyle koşullu toplama yapılır; örneğin tek sorguda hem toplam satışı hem de yalnızca kampanyalı satışı yan yana verebilirsiniz. Pencere fonksiyonları ise satırları kaybetmeden grup içi toplam ve sıralama sağlar; GROUP BY satırı indirger, pencere fonksiyonu indirgemez.

Kullandığınız veritabanı sistemine göre sözdizimi ayrıntıları küçük farklar gösterebilir. Tarih işlemleri ve metin birleştirme en çok ayrışan alanlardır; çalıştığınız sistemin resmî dokümantasyonuna bakmak iyi bir alışkanlıktır.

Mindset programlarında nerede çalışılır?

Mindset kataloğundaki SQL ile Veri Sorgulama (Temel) eğitiminin müfredatında Toplulaştırma Fonksiyonları ve Gruplama modülü, Tablo Birleştirme: JOIN Teknikleri modülü ve Pratik İş Raporları ile Sorgu Geliştirme modülü yer alır. Gruplamayı birleştirme ve raporlama ile birlikte çalışmak isteyenler için bu sıra doğal bir akıştır.

SQL ile Programlama Eğitimi ise Hesaplamalar, Join Kullanımı ve Toplama ve Gruplama modüllerini içeren daha geniş bir yapıdadır; veritabanı oluşturma, tablolarla çalışma ve görüntüleme (views) konularını da kapsar.

İlgili Mindset programı

SQL ile Veri Sorgulama (Temel)

Sık sorulanlar

Sık sorulan sorular

GROUP BY kullanırken neden SELECT'e her sütunu yazamıyorum?

Bir küme birden çok satırdan oluşur ve gruplamayla dışarıda kalan sütunun o kümede tek bir değeri yoktur. Veritabanı hangi satırın değerini göstereceğini bilemediği için hata verir. Çözüm, sütunu GROUP BY listesine eklemek ya da MIN, MAX gibi bir toplama fonksiyonuyla tek değere indirmektir.

COUNT(*) ile COUNT(sütun) aynı sonucu verir mi?

Her zaman değil. COUNT(*) kümedeki tüm satırları sayar. COUNT(sütun) yalnızca o sütunun boş olmadığı satırları sayar. Sütunda boş değer yoksa sonuç aynı çıkar. Boş değer varsa fark, kaç kaydın o bilgiyi eksik taşıdığını gösterdiği için veri kalitesi kontrolünde de kullanışlıdır.

HAVING yerine WHERE kullanabilir miyim?

Koşul toplama sonucuna bağlıysa kullanamazsınız, çünkü WHERE gruplamadan önce çalışır ve henüz toplam hesaplanmamıştır. Koşul ham satırdaki bir sütuna bakıyorsa WHERE kullanmak hem doğru hem daha hızlıdır, çünkü gruplamaya girecek satır sayısını baştan azaltır.

GROUP BY ile elektronik tablodaki özet tablo aynı şey mi?

Amaç aynıdır: satırları kategoriye göre toplamak. Fark ölçeklenebilirlikte ve tekrarlanabilirlikte yatar. SQL sorgusu çok büyük tablolarda çalışır, aynı sorgu her hafta yeniden çalıştırılabilir ve başka sorgulara bağlanabilir. Özet tablo ise elle kurulur ve veri sınırına takılabilir.

Gruplanmış sonucu nasıl sıralarım ve ilk birkaç satırı nasıl alırım?

Sorgunun sonuna ORDER BY ile toplama sonucunun takma adını yazarsınız, yüksekten düşüğe sıralamak için DESC eklersiniz. İlk satırları almak için sistemine göre LIMIT ya da TOP ifadesi kullanılır; hangisinin geçerli olduğu kullandığınız veritabanına bağlıdır.

SQL GROUP BY ile Veri Özetleme: Adım Adım Anlatım