İçeriğe geç

SQL’de GROUP BY ve HAVING: Verileri Gruplamak ve Filtrelemek

Şimdi düşününce, SQL’de veriyle uğraşırken bazen sanki bir yığın lego parçasıyla oynuyormuşum gibi hissediyorum. Hani elinde binlerce renkli parça var ve sen onlardan anlamlı bir bütün çıkarmaya çalışıyorsun ya, işte veritabanı sorguları da biraz öyle.

Özellikle büyük veri setleriyle çalışırken, “bana sadece şunu göster” demek yetmiyor. Bir de “şu şu kriterlere uyanları grupla ve sonra da o gruplardan sadece belirli olanları seç” demen gerekiyor. İşte tam da bu noktada, SQL’in süper kahramanları GROUP BY ve HAVING devreye giriyor. Açıkçası ben ilk başlarda bunları biraz karıştırıyordum, hani fonksiyonları birbirine benzetirsin ya, işte öyle bir şeydi benim için. Ama sonra oturdu kafamda tabii.

Öncelikle, GROUP BY‘dan bahsedelim. Bu arkadaş, senin bir sütundaki benzersiz değerlere göre satırlarını gruplamanı sağlıyor. Mesela bir e-ticaret sitesinin sipariş veritabanı var diyelim. Sen de diyorsun ki, “Hangi şehirde en çok sipariş vermişim, bana bir liste yap.” İşte tam burada GROUP BY SehirAdi komutu işe yarıyor. Bu komutla birlikte, her bir şehrin adını bir kere görüyor ve o şehre ait tüm siparişleri tek bir çatı altında topluyorsun. Tabi tek başına bu yeterli değil, hani derler ya “ne işe yarıyor bu?” diye, işte tam da o noktada devreye COUNT, SUM, AVG gibi toplama fonksiyonları giriyor. Mesela COUNT(*) ile her şehirdeki sipariş sayısını öğrenebilirsin.

Şimdi, bu GROUP BY olayı güzel de, bazen elde ettiğin gruplardan sadece belirli olanları seçmek isteyebilirsin, değil mi? Mesela az önceki sipariş örneğinde, sadece 100’den fazla siparişi olan şehirleri görmek istedin. İşte o zaman HAVING anahtar kelimesi imdadına yetişiyor. HAVING, tıpkı WHERE gibi bir filtreleme yapar ama farkı şurada; WHERE bireysel satırları filtrelerken, HAVING, GROUP BY ile oluşturduğun grupları filtreler. Yani, “bana 100’den fazla siparişi olan şehirleri göster” dediğinde, önce GROUP BY SehirAdi ile şehirleri grupluyorsun, sonra HAVING COUNT(*) > 100 ile bu gruplardan sadece belirli olanları seçiyorsun. Ne güzel değil mi?

Gerçi ben ilk başlarda WHERE ile HAVING‘i karıştırmaktan bayağı bir baş ağrısı çekmiştim. Sanki birisi “bu satırı al” diyor, öbürü “bu grubu al” diyor ama hangisi hangisiydi, tam emin olamıyorsun. Neyse efendim, zamanla insan öğreniyor bunları. Açıkçası, veritabanı sorgularını daha anlamlı hale getiriyor bu ikili. Büyük veri setlerini analiz ederken, işini o kadar kolaylaştırıyor ki, sanki sihirli bir değnek değmiş gibi oluyor.

Bir örnekle pekiştirelim, ne dersin? Diyelim ki elimizde bir Urunler tablosu var ve bu tabloda KategoriAdi ve Fiyat sütunları bulunuyor. Biz de şunu öğrenmek istiyoruz: “Hangi kategorideki ürünlerin ortalama fiyatı 50 TL’den fazladır?” İşte bunu yapmak için önce ürünleri kategorilerine göre gruplamamız, sonra da her grubun ortalama fiyatını hesaplayıp, bu ortalamanın 50’den büyük olduğu grupları seçmemiz gerekiyor.

Kod Örneği

Şöyle bir sorgu işimizi görecektir:

-- YANLIŞ KULLANIM ÖRNEĞİ (HAVING yerine WHERE ile filtreleme) SELECT KategoriAdi, AVG(Fiyat) AS OrtalamaFiyat FROM Urunler WHERE AVG(Fiyat) > 50 -- Bu kısım hata verir çünkü AVG fonksiyonu WHERE'den önce çalışmaz GROUP BY KategoriAdi;

Gördüğünüz gibi, yukarıdaki sorgu çalışmayacaktır. Çünkü AVG(Fiyat) gibi bir toplama fonksiyonunu WHERE anahtar kelimesiyle filtrelemeye çalıştığınızda hata alırsınız. WHERE, her bir satır için ayrı ayrı çalışır, gruplama henüz yapılmamıştır. Bu yüzden AVG(Fiyat)‘ın ne olduğunu bilmez.

Doğrusu ise şöyle:

-- DOĞRU KULLANIM ÖRNEĞİ (GROUP BY ve HAVING ile) SELECT KategoriAdi, AVG(Fiyat) AS OrtalamaFiyat FROM Urunler GROUP BY KategoriAdi HAVING AVG(Fiyat) > 50;

İşte bu kadar basit! Önce GROUP BY KategoriAdi ile ürünleri kategorilerine göre grupladık, sonra da HAVING AVG(Fiyat) > 50 diyerek, ortalama fiyatı 50 TL’den yüksek olan kategorileri seçtik. Tabii bu sadece basit bir örnek. Gerçek hayatta çok daha karmaşık sorgularla uğraşmak durumunda kalıyoruz, hani bazen bir rapor hazırlarken saatlerce sorgu yazıp durursun ya, işte öyle bir şey. Ama neticede, bu iki komutu doğru kullanmak, veriden anlamlı sonuçlar çıkarmak için gerçekten hayat kurtarıcı.

Bu arada, bu konuyu daha detaylı incelemek isterseniz, Google’da arama yapabilirsiniz. Bir sürü kaynak çıkacaktır karşınıza. Hatta YouTube’da bile bununla ilgili anlatımlar var sanırım, bir bak isterseniz.

Neticede, GROUP BY ve HAVING, SQL’in olmazsa olmazları arasında yer alıyor. Veriyi anlamlandırmak, özetlemek ve belirli gruplar üzerinde analiz yapmak için bu ikiliyi iyi öğrenmek gerekiyor. Bana göre, bu komutlar veritabanı sorgularının derinliğini ve gücünü ortaya koyuyor. Yoksa sadece satırları çekip durursun, ne anlamı kalır ki değil mi?

Şimdi düşününce, ilk zamanlar bu komutları öğrenirken bayağı bir zorlandığımı hatırlıyorum. Hani bir keresinde, bir rapor için GROUP BY ve HAVING kullanmam gerekiyordu ama WHERE ile HAVING‘i karıştırıp duruyordum. Sonunda bir türlü istediğim sonucu alamadım ve kendi yazdığım sorgu sınıfta kaldı resmen. Sonra bir arkadaşım gösterdi, meğersem çok basit bir hataymış. O gün anladım ki, teknik konuları öğrenirken bazen birinden yardım almak veya bol bol pratik yapmak şart.

Bu yüzden, siz de eğer veriyle uğraşıyorsanız, bu komutları bol bol deneyin. Kendi basit tablolarınızı oluşturup, farklı senaryolarla test edin. Hata yapmaktan korkmayın, çünkü en iyi öğrenme yolu aslında hatalardan geçiyor. Tabi bunu söylerken kendi programım sınıfta kaldı :))

Umarım bu yazı, GROUP BY ve HAVING konusunu biraz daha anlaşılır hale getirmiştir. Unutmayın, veritabanı sorguları sadece birer komut dizisi değil, aynı zamanda veriye anlam katmanın, onu şekillendirmenin bir yolu. İşte bu yüzden bu işler eğlenceli.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.