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
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
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
27 Mayıs 2011 at 06:01
eline saglik guzel olmus
ama
kodlardaki kisiler tirnak icinde olmamali
27 Mayıs 2011 at 13:18
Kodları PhpMyAdmin’de test ediyorum. Orada nedense bu tırnakları ekliyor sistem.
28 Mart 2015 at 19:35
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
22 Aralık 2011 at 08:39
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:)
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.
27 Aralık 2011 at 07:21
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?
19 Şubat 2012 at 11:59
Hepsini çok Güzel Anlatmişin kardeş Allah razi olsun :=) Çok güzel yararlandik 🙂
18 Mart 2012 at 09:11
Ellerine sağlık çok yararlı bir paylaşım olmuş..
18 Mart 2012 at 09:11
Ellerine sağlık çok yararlı bir makale olmuş..
05 Nisan 2012 at 11:13
hiçde güzel olmamış.. ama yinede elinize sağlık
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.
04 Mayıs 2012 at 01:32
bilgiler için teşekkü ederim.delphi de bilginiz var mı?bir sorunum vardı da.o sorunuma çzöüm ararken sizin siteye rasladım…
04 Mayıs 2012 at 07:26
Delphi bilmiyorum. Yardımcı olamayacağım.
06 Haziran 2012 at 00:57
SELECT * FROM `kisiler` GROUP BY ülke
dediğin zaman ORA-00979: Not a GROUP BY hatası alırsın.
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.
24 Ağustos 2012 at 02:04
“SELECT ULKE FROM `kisiler` GROUP BY ülke” burda hata veriyo SELECT ULKE FROM KISILER GROUP BY ULKE şeklinde olması gerekiyo saygılarımla..
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.
24 Ağustos 2012 at 06:35
vaktiniz varsa size bişey sormak istiyorum sql le ilgili
24 Ağustos 2012 at 06:46
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
28 Ağustos 2012 at 14:45
Güzel anlatım emeğinize sağlık.
28 Ağustos 2012 at 23:44
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?
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 Kasım 2012 at 14:23
gayet anlaşılır şekilde açıklamış teşekkürler
02 Aralık 2012 at 11:45
Elleriniz dert görmesin hocam. Çok faydalı bir makale olmuş.
10 Aralık 2012 at 02:42
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…
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ı.
24 Aralık 2012 at 06:18
Emeğinize sağlık cok güzel bir anlatım olmuş
27 Mart 2013 at 07:58
gerçekten güzel bir makale olmuş, teşekkürler.
05 Mayıs 2013 at 11:08
Çok Güzel olmuş hocam ellerinize sağlık.
19 Mayıs 2013 at 15:51
çok güzel olmuş admin kardeş
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
04 Ekim 2013 at 02:45
Harika bir anlatım olmuş ellerine ve bilgine sağlık 😀
05 Aralık 2013 at 00:34
Gercekten cok ayrintili ve guzel anlatmışsınız. Emeğinize sağlık.
13 Aralık 2013 at 06:27
İ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.
04 Ocak 2014 at 07:00
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.
02 Mart 2014 at 05:46
anlatım ve örnekler süper olmuş daha iyi anladım çok teşekkürler emeği geçenlere
29 Mart 2014 at 14:11
Siteniz gerçekten emek kokuyor teşekkürler
30 Mart 2014 at 12:43
neden avg (maaş)da maaş nvarchar olmaz ? men test etdimde yalniz tid secdikde olur
01 Nisan 2014 at 07:17
maaşın sayısal (scalar) bir değer olması gerekiyor ortalamasının alınabilmesi için.
01 Nisan 2014 at 05:22
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
24 Nisan 2014 at 03:57
Emeğinize sağlık çok güzel olmuş.
24 Mayıs 2014 at 10:50
şimdiye kadar o kadar site inceledim ama bu gördüğüm en açıklayıcı ve yararlı site..emeğinize sağlık..
16 Temmuz 2014 at 07:12
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.
13 Mart 2015 at 03:13
Sql kodları gayet iyi anlatılmış.Tesekkurler..
17 Mart 2015 at 02:42
Çok da güzel olmuş çok da iyi olmuş . Herkesin makalesine kimse karışamaz 🙂
21 Mayıs 2015 at 09:06
Ellerine sağlık kardeşim çalışmama çok faydan oldu,teşekkürlerimi sunuyorum.
08 Eylül 2015 at 06:30
Güzel anlatım hocam. Derslerinizin bir çoğunu inceledim. Çok faydalandım. Teşekkürler.
02 Ekim 2015 at 02:48
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:)
08 Aralık 2015 at 09:05
güzel olmuş. teşekkürler
05 Mayıs 2016 at 01:37
Güzel makale teşekkürler
01 Haziran 2016 at 08:53
emeğine sağlık, güzel anlatım olmuş.