Harun Reşit Zafer

bâki kalan bu kubbede bir hoş sadâ imiş

SQL 15: GROUP BY İfadesi

Schema SQL
Bir önceki makalede SQL kümeleme fonksiyonlarını anlatmıştık. Çünkü kümeleme fonksiyonları genelde GROUP BY ifadesi ile birlikte kullanılır. Adından da anlaşılacağı üzere GROUP BY ifadesi gruplama yapar. Yani sonuç kümesini bir veya birden fazla kolona göre gruplar. Öncelikle bir önceki makalede de kullandığımız aşağıdaki kisiler tablosunu inceleyelim. Sonra bu tablo üzerinde biraz gruplama yapacağız.

Not: Bu arada diğer SQL derslerine buradan ulaşabilirsiniz

id Ad Soyad Yas Cinsiyet Şehir Ülke Maaş
2 Ahmet Yılmaz 20 1 Ankara Türkiye 2000
3 Mehmet Efe 22 1 Bolu Türkiye 2000
4 Ayşe Can 23 0 İstanbul Türkiye 3500
5 Fatma Ak 35 0 Ankara Türkiye 3200
6 John Smith 45 1 New York USA 3500
7 Ellen Smith 40 0 New York USA 3500
8 Hans Müller 30 1 Berlin Almanya 4000
9 Frank Cesanne 35 1 Paris Fransa 3700
10 Abbas Demir 26 1 Adana Türkiye 2000
11 Hatice Topçu 26 0 Hatay Türkiye 2200
12 Gülsüm Demir 35 0 Adana Türkiye 2000

Şimdi yukarıdaki tabloyu ülkelere göre gruplasaydık ne olurdu? Görüldüğü gibi 4 farklı ülke olduğuna göre 4 farklı grup oluşacaktı. Bu gruplar Türkiye’de çalışanlar, Amerika’da çalışanlar, Fransa’da çalışanlar ve Almanya’da çalışanlar olarak ifade edilebilir. Bu ifade biçimi oldukça anlaşılır zira saf Türkçe. Biraz daha teknik bir ifade kullanmak istersek; Ülke alanında Türkiye, Amerika, Fransa veya Almanya değerleri bulunan kayıtların gruplaşması diyebiliriz.

Hemen bu örneği sorgu olarak yazalım:

 SELECT ülke FROM `kisiler` GROUP BY ülke

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke
Almanya
Fransa
Türkiye
USA

Burada SELECT ifadesinden sonra ülke kolonu dışında kolonlar yazarsak, bu kolonlar için gelecek olan değerler anlamlı olmayacaktır. Mesela:

SELECT * FROM `kisiler` GROUP BY ülke

Anlamsız sonuçlar verir :

id Ad Soyad Yas Cinsiyet Şehir Ülke Maaş
8 Hans Müller 30 1 Berlin Almanya 4000
9 Frank Cesanne 35 1 Paris Fransa 3700
2 Ahmet Yılmaz 20 1 Ankara Türkiye 2000
6 John Smith 45 1 New York USA 3500

Sonuç kümesine baktığımızda ülke alanı hariç diğer alanlar için gruba ait kayıtlardan ilkinin değerlerinin geldiğini görürüz. Bu da yukarıdaki tabloyu anlamsız kılıyor. Bütün bunları anlatmamın sebebi GROUP BY’ın kümeleme fonksiyonları ile nasıl anlamlı hale geldiğini göstermek.

Örneğin ülkelerin ortalama maaşını görmek istesek:

SELECT ülke, AVG(maaş) FROM `kisiler` GROUP BY ülke

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke AVG(maaş)
Almanya 4000.0000
Fransa 3700.0000
Türkiye 2414.2857
USA 3500.0000

Burada geri planda kayıtlar ülke değerlerine göre gruplandı ve her grubun maaş değerinin ortalaması hesaplanarak yukarıdaki sonuç kümesi elde edildi. Sonuç olarak GROUP BY kullanırken SELECT’ten sonra GROUP BY ile kullandığımız alanları ve kümeleme fonksiyonlarını kullanmamız gerekiyor.

Eğer her ülkeden kaç çalışanın olduğunu görmek istersek:

SELECT ülke, COUNT(*) AS sayı FROM `kisiler` GROUP BY ülke

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke sayı
Almanya 1
Fransa 1
Türkiye 7
USA 2

Örneğin maaş ortalamasını bayanlar ve erkekler olarak görmek isteseydik:

SELECT cinsiyet, AVG(maaş) AS sayı FROM `kisiler` GROUP BY cinsiyet

Sorgunun çıktısı aşağıdaki gibi olacaktır:

cinsiyet sayı
0 2880.0000
1 2866.6667

GROUP BY ile birden fazla alan kullanımı

GROUP BY ifadesinden sonra birden fazla alan kullanabiliriz. Örneğin kayıtları önce ülkelere göre gruplayıp sonra her bir grubu kendi içinde şehirlere göre gruplamak istesek:

SELECT ülke, şehir FROM `kisiler` GROUP BY ülke, şehir

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke şehir
Almanya Berlin
Fransa Paris
Türkiye Adana
Türkiye Ankara
Türkiye Bolu
Türkiye Hatay
Türkiye İstanbul
USA New York

Türkiye dışındaki gruplarda tek bir şehir varken, Türkiye grubunun da kendi içinde 5 gruba ayrıldığına dikkat edin. Her bir gruba ait kaç adet çalışan olduğunu görmek istersek sorguya ufak bir ekleme yapmamız yeterli olur:

SELECT ülke, şehir, COUNT(*) FROM `kisiler` GROUP BY ülke, şehir

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke şehir COUNT(*)
Almanya Berlin 1
Fransa Paris 1
Türkiye Adana 2
Türkiye Ankara 2
Türkiye Bolu 1
Türkiye Hatay 1
Türkiye İstanbul 1
USA New York

Şimdi de her ülke için bayan ve erkek çalışanların sayısını ve yaş ortalamalarını bulalım:

SELECT ülke, cinsiyet, AVG(yas), COUNT(*) FROM `kisiler` GROUP BY ülke, cinsiyet

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke cinsiyet AVG(yas) COUNT(*)
Almanya 1 30.0000 1
Fransa 1 35.0000 1
Türkiye 0 29.7500 4
Türkiye 1 22.6667 3
USA 0 40.0000 1
USA 1 45.0000 1

Yukarıdaki tablodan mesela, Türkiye’den 4 bayan, 3 erkek çalışanın olduğunun ve bayanların yaş ortalamalarının 29.7 erkeklerinkinin ise 22.6 olduğunu okuyabiliriz.

GROUP BY İfadesini  WHERE ifadesi ile birlikte kullanmak

Öncelikle WHERE ifadesinin sorguda her zaman group by’dan önce geldiğini belirtelim. Örneğin yukarıdaki sorguya maaşı 2000’den büyük olanlar gibi bir koşul ekleyelim.

SELECT ülke, cinsiyet, AVG(yas), COUNT(*) FROM `kisiler` WHERE maaş > 2000 GROUP BY ülke, cinsiyet

Sorgunun çıktısı aşağıdaki gibi olacaktır:

ülke cinsiyet AVG(yas) COUNT(*)
Almanya 1 30.0000 1
Fransa 1 35.0000 1
Türkiye 0 28.0000 3
USA 0 40.0000 1
USA 1 45.0000 1

Bu sorgu biraz karışık görünse de aslında oldukça basit. Geri planda önce maaşı 2000’den küçük olan kayıtlar elendi. Yani önce sorgunun WHERE kısmı çalıştırıldı. Sonra kalan kayıtlar üzerinde sorgunun geri kalanı çalıştırıldı. Yani asında bir önceki sorgu tüm tablo yerine tablonun alt kümesi (maaşı 2000’den büyük olanlar) üzerinde çalıştırılmış oldu.

Umarım yeterince açık izah edebildim meseleyi. Bir sonraki yazıda yalnızca GROUP BY ile birlikte kullanılan HAVING anahtar sözcüğünü anlatacağım. Yazıda anlayamadığınız ya da “şöyle olsaydı daha anlaşılır olurdu” diyebileceğiniz yerler var ise yorumlara çekinmeden yazın. En kısa zamanda bir tepki veririm.

Herkese Kolay Gelsin

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInPrint this pageEmail this to someone

52 Yorum

  1. erdi sungurtekin

    26 Mart 2011 at 06:14

    Ellerinize saglik cok yararli olmus.Fakultede Group By ile ilgili sunumum var ve cok faydasini goruyorum sizin anlattiklarinizin..Kolay gelsin

  2. eline saglik guzel olmus

    ama

    kodlardaki kisiler tirnak icinde olmamali

    • admin

      27 Mayıs 2011 at 13:18

      Kodları PhpMyAdmin’de test ediyorum. Orada nedense bu tırnakları ekliyor sistem.

      • Hocam kisiler kısmındaki “ silersen sorun olmuyor phpmyadmin tablo ve sütun isimlerini ayırt etmek için öylesine koyuyor “ bunları hiç mi bir işe yaramıyor hayır tabi ki de yarıyor. Örneğin: bazı isimlendirmeler özel karakterler içeriyorsa “-“(tire) gibi algılamada sorun yapıyor bu yüzden “ kullanılması zorunlu hale geliyor.

        Not: Microsoft SQL için “ yerine [] bu kullanılmakta

  3. Harun arkadaş süper bir anlatım yapmışsın. Bence kurslara (Bilge Adam, Netron, vs…) avuç dolusu para veren adamlar senin bu anlatımını görünce çok pişman olacaklar. şaka bir yana çok güzel anlatmışsın. Devamlı siteni takip edicem çok faydalı şeyler anlatıyorsun. Bak seni bu kadar övdüm diye hız kesmece, tamam ben top seviyede biliyorum anlatabiliyorum diye makaleler yazmamacalık etme sonra sana küseriz:)

    • admin

      22 Aralık 2011 at 09:15

      Teşekkürler. Uzun zamandır aldığım en iyi yorum :) Yeni makaleler için tek sorunum zaman. Zaman buldukça yazmaya devam edeceğim inşallah.

  4. kardeş ellerine sağlık çok güzel anlatmışsın yalnız farklı iki tabodaki sutunları sum ile nasıl toplayabiliriz yardımcı olurmusun?

  5. Hepsini çok Güzel Anlatmişin kardeş Allah razi olsun :=) Çok güzel yararlandik :)

  6. Ellerine sağlık çok yararlı bir paylaşım olmuş..

  7. Ellerine sağlık çok yararlı bir makale olmuş..

  8. hiçde güzel olmamış.. ama yinede elinize sağlık

    • admin

      05 Nisan 2012 at 12:14

      teşekkürler. Bu arada bağlaç olan de ayrı yazılır. “hiç de güzel olmamış”, “yine de elinize sağlık” örneklerinde olduğu gibi.

  9. bilgiler için teşekkü ederim.delphi de bilginiz var mı?bir sorunum vardı da.o sorunuma çzöüm ararken sizin siteye rasladım…

  10. SELECT * FROM `kisiler` GROUP BY ülke

    dediğin zaman ORA-00979: Not a GROUP BY hatası alırsın.

    • admin

      06 Haziran 2012 at 04:22

      Makaleyi yazalı uzun zaman oldu. Ama hatırladığım kadarıyla sorguların hepsi çalıştırıp test etmiştim.

  11. “SELECT ULKE FROM `kisiler` GROUP BY ülke” burda hata veriyo SELECT ULKE FROM KISILER GROUP BY ULKE şeklinde olması gerekiyo saygılarımla..

    • admin

      24 Ağustos 2012 at 05:46

      Ben sorguları phpmyadmin’de denemiştim. Orada bu tek tırnakları tablo isimlerine otomatik olarak ekliyor ve hatasız çalışıyor. Bir de eklenen kararkter ` karakteri değil.

  12. vaktiniz varsa size bişey sormak istiyorum sql le ilgili

  13. benim 3 tane tablom var ürünler,ülkeler onlardan sonrada satışlar diye satış tablosunda urunıd,ulkeıd ve satis(urunlerin satış sayılarını içeriyo) colonları var ben her ülkenin en fazla sattığı 5 ürünü bulmak istiyorum ama ulke ismi ve ürün ismi ile birlikte gelicek en çok satılan 5 ürün yardımcı olur musunuz acil

  14. Güzel anlatım emeğinize sağlık.

  15. Makale oldukça güzel olmuş fakat bir soru belirdi kafamda. Group By ifadesinde performans nasıl?
    Kastettiğim şeyi verdiğiniz örnek üzerinden anlatacak olursak; 50.000 kaydımız olduğunu düşünelim. Ülke bazlı bir arama yapacağız veya sadece ülkeleri listeleyeceğiz. Harici bir tabloda ülkeleri bulundurmak ile group by arasında ne gibi performans farklılıkları olur? Sonuçta 50 ülkeyi 50 satırlık tablodan çekmekle 50.000 kayıt içerisinde group by ile ülkeleri ayıklamak arasında bir fark olmalı. Bu fark ne kadar büyüktür? Gözardı edilebilir mi?

    • admin

      29 Ağustos 2012 at 04:44

      Eğer bu listeye sık olarak erişecekseniz elbette ayrı bir listede tutmak daha elverişli olacaktır. Ki gerçek uygulamalarda böyle yapılıyor genellikle.

  16. gayet anlaşılır şekilde açıklamış teşekkürler

  17. Elleriniz dert görmesin hocam. Çok faydalı bir makale olmuş.

  18. Merhaba
    öncelikler paylaşımlarınız için Allah razı olsun.

    benim bu konuyla alakalı bir problemim var ve çözemiyorum. SQL veritabanını kullanıyorum. URUNLER tablosunda stok numarası, malzeme adı, sehir kolonları mevcut
    SELECT [STOK NUMARSI],[MALZEME ADI],[SEHIR], COUNT(*) AS ADET FROM URUNLER GROUP BY [STOK NUMARASI]
    bu kodu çalıştırdığımda hata alıyorum ben şöyle bir görüntü istiyorum
    STOK NUMARASI MALZEME ADI SEHIR ADET
    987389742 Ütü masası İstanbul 89
    328942339 Bilgisayar masası Yozgat 46

    bu görümü ihtiyacım var yardımcı olursanız sevinirim
    kolay gelsin saygılar…

    • admin

      10 Aralık 2012 at 03:55

      Bu sorgu eğer stok_numarasi alanı ürün_id gibi bir şey ise her üründen kaç adet olduğunu gösterir. Eğer her üründen her şehirde kaçar adet olduğunu göstermek istiyorsanız “group by şehir, stok numarası” gibi olmalı.

  19. Emeğinize sağlık cok güzel bir anlatım olmuş

  20. gerçekten güzel bir makale olmuş, teşekkürler.

  21. Çok Güzel olmuş hocam ellerinize sağlık.

  22. çok güzel olmuş admin kardeş

  23. yusuf akdeniz

    21 Haziran 2013 at 02:36

    Gerçekten çok güzel anlatmışsınız sql’i baştan öğreniyorum şu an emeğe saygı çok çok teşekkürler tekrardan

  24. Harika bir anlatım olmuş ellerine ve bilgine sağlık 😀

  25. Gercekten cok ayrintili ve guzel anlatmışsınız. Emeğinize sağlık.

  26. İnternet’te Java kütüphaneleri hakkında bilgi ararken siteniz çıktı karşıma. Anlatımlara çok emek harcamışsınız. Ellerinize Sağlık.

  27. eline sağlık abicim finallerde cok işime yarayacak tüm bağlantılarınada tek tek bakıyorum cok güzel bi anlatım olmuş eline sağlık.

  28. anlatım ve örnekler süper olmuş daha iyi anladım çok teşekkürler emeği geçenlere

  29. Siteniz gerçekten emek kokuyor teşekkürler

  30. neden avg (maaş)da maaş nvarchar olmaz ? men test etdimde yalniz tid secdikde olur

    • admin

      01 Nisan 2014 at 07:17

      maaşın sayısal (scalar) bir değer olması gerekiyor ortalamasının alınabilmesi için.

  31. Gerçekten çok açık ve anlaşılır bir anlatım olmuş okuldaki veri tabanı hocamdan hiç birşey anlamadığımı farkettim. Ellerinize sağlık

  32. Emeğinize sağlık çok güzel olmuş.

  33. şimdiye kadar o kadar site inceledim ama bu gördüğüm en açıklayıcı ve yararlı site..emeğinize sağlık..

  34. Staj dönemimde de çalışma hayatımda da sık sık faydalandığım bi kaynak burası, bu isim marka olmalı..emeğinize sağlık.

  35. Sql kodları gayet iyi anlatılmış.Tesekkurler..

  36. Çok da güzel olmuş çok da iyi olmuş . Herkesin makalesine kimse karışamaz :)

  37. Ellerine sağlık kardeşim çalışmama çok faydan oldu,teşekkürlerimi sunuyorum.

  38. Güzel anlatım hocam. Derslerinizin bir çoğunu inceledim. Çok faydalandım. Teşekkürler.

  39. elinize sağlık group by ‘ın tamam grupluyor da “select *” ile çekildiğinde anlamsız olması neye yarıyor bu şimdi soru işaretini kaldırdı kafamda:)

  40. güzel olmuş. teşekkürler

  41. Güzel makale teşekkürler

  42. emeğine sağlık, güzel anlatım olmuş.

1 Pingback

  1. Anonim

Bir Cevap Yazın

E-posta adresiniz yayınlanmayacak

*

© 2016 Harun Reşit Zafer

Temayı tasarlayanAnders NorenYukarı ↑