Berk Akademi
Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

SQL DISTINCT ve GROUP BY Farkı: Uygulamalı Rehber

sql-distinct-ve-group-by-farki
Bu yazıda neler var?
  1. Önce Sonuç Satırının Ne Anlattığını Belirleyin
  2. DISTINCT ile Benzersiz Müşteri Listesi Nasıl Oluşturulur?
  3. GROUP BY ile Müşteri Başına Sipariş Sayısını Hesaplayın
  4. COUNT(DISTINCT) Ne Zaman Gereklidir?
  5. DISTINCT, GROUP BY ve COUNT(DISTINCT) Kararını Çıktıyla Karşılaştırın
  6. Beklenmeyen Sonuçları Teşhis Etmek İçin SQL Kontrol Listesi
  7. Sık Sorulan Sorular

SQL DISTINCT ve GROUP BY farkı, sorgunun sonunda nasıl bir çıktı istediğinle ilgilidir. Benzersiz müşteri listesi oluşturmak için genellikle SELECT DISTINCT kullanılır; müşteri başına sipariş sayısı gibi hesaplamalar gerektiğinde ise GROUP BY tercih edilir. Ancak doğru seçimi yapmadan önce, sorgu sonucundaki bir satırın neyi temsil ettiğini belirlemek gerekir.

Aşağıdaki örneklerde müşteriler ve siparişler tablolarını birlikte kullanacağız. Böylece JOIN sonrasında oluşan satırları inceleyip DISTINCT’in tekrarları nasıl kaldırdığını adım adım görebilirsiniz.

Önce Sonuç Satırının Ne Anlattığını Belirleyin

Bir SQL sorgusunu yazmadan önce şu soruyu sorun: Bir satır bir müşteri mi, bir sipariş mi, yoksa bir müşteri-kategori eşleşmesi mi? Bu sorunun cevabı, sorguda DISTINCT veya GROUP BY kullanıp kullanmayacağınızı doğrudan etkiler.

Örneğin musteriler tablosunda müşteriler, siparisler tablosunda ise her siparişin hangi müşteriye ait olduğu tutuluyor olsun:

müşteri_id müşteri_adı
1 Ayşe
2 Mehmet
3 Zeynep
sipariş_id müşteri_id kategori
101 1 Elektronik
102 1 Kitap
103 2 Kitap
104 3 Elektronik
105 3 Elektronik

Bu iki tabloyu müşteri kimliği üzerinden birleştirelim:

SELECT
    m.müşteri_id,
    m.müşteri_adı,
    s.sipariş_id,
    s.kategori
FROM musteriler AS m
JOIN siparisler AS s
    ON m.müşteri_id = s.müşteri_id;

Sonuçta beş satır elde edilir. Ayşe iki sipariş verdiği için iki satırda, Zeynep de iki sipariş verdiği için iki satırda görünür. Bu durum bir hata değildir; JOIN sonucundaki doğal satır düzeyi müşteri-sipariş düzeyidir.

müşteri_adı sipariş_id kategori
Ayşe 101 Elektronik
Ayşe 102 Kitap
Mehmet 103 Kitap
Zeynep 104 Elektronik
Zeynep 105 Elektronik

Kontrol noktası: Sorgunun satır düzeyi müşteri-sipariş ise beklenen satır sayısı, eşleşen sipariş sayısına yakın olur. Hedefiniz her müşteriyi yalnızca bir kez göstermekse sonuç düzeyini müşteri olarak yeniden düşünmeniz gerekir.

DISTINCT ile Benzersiz Müşteri Listesi Nasıl Oluşturulur?

DISTINCT ile Benzersiz Müşteri Listesi Nasıl Oluşturulur?

JOIN sonucunda aynı müşterinin birden fazla kez görünmesini istemiyorsanız, müşteri bilgilerini seçerek DISTINCT kullanabilirsiniz:

SELECT DISTINCT
    m.müşteri_id,
    m.müşteri_adı
FROM musteriler AS m
JOIN siparisler AS s
    ON m.müşteri_id = s.müşteri_id;

Bu sorgunun beklenen çıktısı üç satırdır:

müşteri_id müşteri_adı
1 Ayşe
2 Mehmet
3 Zeynep

Burada DISTINCT, seçilen sütunların birlikte oluşturduğu aynı satır kombinasyonlarını tekilleştirir. Yalnızca m.müşteri_id seçilirse her kimlik bir kez görünür. Ancak müşteri kimliğinin yanına kategori eklerseniz sonuç artık müşteri-kategori kombinasyonlarını temsil eder. Örneğin Zeynep’in iki Elektronik siparişi yine tek satıra iner; fakat aynı müşterinin Kitap ve Elektronik siparişleri varsa iki farklı satır oluşur.

Bu nedenle DISTINCT toplama yapmaz, sipariş sayısını hesaplamaz ve gruplara değer üretmez. Yalnızca sonuç kümesindeki tekrar eden sütun kombinasyonlarını kaldırır. Sorgu sonuçlarını adım adım izleyerek öğrenmek isteyenler, uygulamalı video eğitimleri üzerinden bu tür sorguların çalışma mantığını tekrar tekrar inceleyebilir.

GROUP BY ile Müşteri Başına Sipariş Sayısını Hesaplayın

Her sonuç satırının bir müşteriyi temsil etmesini ve o müşterinin sipariş sayısını göstermesini istiyorsan GROUP BY kullanmalısın. Örneğin müşteri tablosunda Ada, Mert ve Selin; sipariş tablosunda ise bu müşterilere ait sırasıyla 3, 1 ve 2 sipariş bulunduğunu düşünelim.

SELECT
    m.musteri_id,
    m.musteri_adi,
    COUNT(*) AS siparis_sayisi
FROM musteriler AS m
JOIN siparisler AS s
    ON s.musteri_id = m.musteri_id
GROUP BY
    m.musteri_id,
    m.musteri_adi;

Beklenen çıktı şöyledir:

musteri_id musteri_adi siparis_sayisi
1 Ada 3
2 Mert 1
3 Selin 2

Burada GROUP BY, tekrar eden müşteri değerlerini yalnızca görünümden kaldırmaz. Aynı müşteriye ait sipariş satırlarını bir grup hâline getirir ve COUNT(*) ile her grup için bir hesaplama yapılmasını sağlar.

Yalnızca birden fazla siparişi bulunan müşterileri görmek için toplulaştırılmış sonuç HAVING ile filtrelenebilir:

SELECT
    m.musteri_id,
    m.musteri_adi,
    COUNT(*) AS siparis_sayisi
FROM musteriler AS m
JOIN siparisler AS s
    ON s.musteri_id = m.musteri_id
GROUP BY
    m.musteri_id,
    m.musteri_adi
HAVING COUNT(*) > 1;

Bu sorgu Ada ve Selin’i döndürür. WHERE, tek tek kayıtları gruplama işleminden önce filtreler. HAVING ise gruplar oluşturulup sipariş sayıları hesaplandıktan sonra sonucu filtreler. Dolayısıyla sipariş tarihi gibi satır düzeyindeki koşullar WHERE, “sipariş sayısı birden fazla olan müşteriler” gibi toplulaştırma koşulları HAVING bölümünde kullanılır.

COUNT(DISTINCT) Ne Zaman Gereklidir?

COUNT(DISTINCT) Ne Zaman Gereklidir?

Bir sipariş, sipariş ürünleri tablosuyla birleştirildiğinde içerdiği her ürün satırı nedeniyle birden fazla kez görünebilir. Ada’nın verilerinin JOIN sonrasında şu şekilde oluştuğunu düşünelim:

siparis_id musteri_id urun_id
101 1 10
101 1 11
102 1 10
103 1 12

Bu tabloda dört kayıt vardır; ancak yalnızca üç benzersiz sipariş ve üç benzersiz ürün bulunur.

SELECT
    musteri_id,
    COUNT(*) AS toplam_satir,
    COUNT(DISTINCT siparis_id) AS benzersiz_siparis,
    COUNT(DISTINCT urun_id) AS benzersiz_urun
FROM siparis_urunleri
GROUP BY musteri_id;

Beklenen sonuç toplam_satir = 4, benzersiz_siparis = 3 ve benzersiz_urun = 3 olur. COUNT(*) JOIN sonucundaki bütün satırları sayarken COUNT(DISTINCT siparis_id) tekrarlanan sipariş kimliklerini bir kez sayar.

İki yapının görevi farklıdır: GROUP BY, müşteri başına ayrı bir sonuç satırı üretir; COUNT(DISTINCT sütun) ise her müşteri grubunda kaç farklı değer bulunduğunu ölçer. Bu nedenle önce sonucun hangi düzeyde üretileceğini, ardından satırların mı yoksa benzersiz değerlerin mi sayılacağını belirlemelisin.

DISTINCT, GROUP BY ve COUNT(DISTINCT) Kararını Çıktıyla Karşılaştırın

Aynı sipariş kayıtları üzerinde farklı bir sonuç granülerliği hedeflediğimizi düşünelim. Örnek veride Ayşe’nin üç, Bora’nın iki siparişi olsun. Ayşe iki farklı ürün kategorisinden, Bora ise yalnızca bir kategoriden sipariş vermiş olsun.

Sorgunun amacı Temel yaklaşım Beklenen satır düzeyi Örnek sonuç
Sipariş veren benzersiz müşterileri listelemek SELECT DISTINCT musteri_id, musteri_adi Her müşteri için bir satır Ayşe
Bora
Müşteri başına sipariş sayısını bulmak GROUP BY musteri_id, musteri_adi ve COUNT(*) Her müşteri için bir özet satırı Ayşe: 3
Bora: 2
Müşteri başına benzersiz kategori sayısını bulmak COUNT(DISTINCT kategori) Her müşteri için bir özet satırı Ayşe: 2
Bora: 1

DISTINCT ve GROUP BY, yalnızca müşteri sütunlarını seçtiğin basit sorgularda benzer sonuçlar üretebilir. Ancak doğru aracı belirleyen şey görünüş değil, sorgunun amacı ve sonuçtaki bir satırın neyi temsil edeceğidir.

Beş adımlı karar çerçevesi

  1. Beklenen satır düzeyini belirle: Sonuçta her sipariş mi, her müşteri mi, yoksa her müşteri-kategori eşleşmesi mi bir satır olmalı?
  2. Gerekli sütunları seç: Sonuçta kullanılmayacak sütunları sorguya ekleme. Çünkü DISTINCT, seçilen sütunların tamamını bir kombinasyon olarak değerlendirir.
  3. Yalnızca tekrarları kaldıracaksan DISTINCT kullan: Amaç benzersiz müşteri listesi gibi tekilleştirilmiş kayıtlar üretmekse bu yaklaşım uygundur.
  4. Grup başına hesap yapacaksan GROUP BY kullan: Müşteri başına sipariş sayısı, toplam tutar veya ortalama değer gibi hesaplamalar gruplama gerektirir.
  5. Bir sütunun benzersiz değerlerini sayacaksan COUNT(DISTINCT) kullan: Toplam sipariş sayısı yerine müşterinin kaç farklı kategoriden alışveriş yaptığını ölçmek buna örnektir.

Beklenmeyen Sonuçları Teşhis Etmek İçin SQL Kontrol Listesi

Sorgu çalıştığı hâlde beklediğinden fazla, az veya tekrarlı satır döndürüyorsa aşağıdaki kontrolleri sırayla uygula:

  • Sonuçtaki tek bir satırın ne anlama gelmesi gerektiğini açık bir cümleyle yaz.
  • JOIN işleminden önceki ve sonraki satır sayılarını karşılaştır.
  • DISTINCT kullanılan sorguda hangi sütun kombinasyonunun tekilleştirildiğini kontrol et.
  • COUNT(*) ile COUNT(DISTINCT sütun) sonuçlarını bilinçli biçimde karşılaştır.
  • GROUP BY sütunlarının, SELECT listesindeki satır anlamıyla uyumlu olduğundan emin ol.
  • Satırları toplulaştırmadan önce filtrelemek için WHERE, oluşan grupları filtrelemek için gerektiğinde HAVING kullan.
  • Küçük bir örnek veri kümesi hazırlayarak beklenen çıktıyı elle hesapla.

Üç soruluk mini teşhis senaryosu

Bir sorgunun Ayşe için üç satır döndürdüğünü, senin ise müşteri başına tek satır beklediğini düşün. Önce şu soruları yanıtla: Sonuçtaki bir satır müşteriyi mi, siparişi mi temsil ediyor? SELECT listesinde sipariş numarası gibi satırları farklılaştıran bir sütun var mı? Gerçekten tekrarları mı kaldırmak istiyorsun, yoksa müşteri başına bir hesaplama mı yapacaksın?

Sipariş numarası seçilmişse üç satır hata olmayabilir; sonuç sipariş düzeyindedir. Müşteri başına sayı gerekiyorsa sipariş numarasını SELECT listesinden çıkarıp GROUP BY ve COUNT(*) kullanmalısın. Sorunu yalnızca DISTINCT ekleyerek gizlemeye çalışmak, yanlış satır düzeyini düzeltmez. SQL temel bilgini ayrıca ücretsiz SQL ve algoritmik düşünme testleriyle ölçebilirsin.

Sık Sorulan Sorular

DISTINCT ile GROUP BY aynı sorguda birlikte kullanılabilir mi?

Sözdizimsel olarak kullanılabilir; ancak çoğu temel sorguda ikisine birden ihtiyaç duyulmaz. GROUP BY zaten sonucu belirtilen gruplar düzeyinde üretir. Eklenen DISTINCT sonucu değiştirmiyorsa gereksizdir ve sorgunun asıl amacını belirsizleştirebilir.

COUNT(*) ile COUNT(DISTINCT sütun) arasındaki fark nedir?

COUNT(*) gruptaki satırları sayar. COUNT(DISTINCT sütun) ise belirtilen sütundaki benzersiz ve NULL olmayan değerleri sayar. Örneğin üç siparişte iki farklı kategori varsa sonuçlar sırasıyla 3 ve 2 olur.

HAVING yerine WHERE kullanırsam müşteri başına sipariş sayısını filtreleyebilir miyim?

WHERE, satırları gruplama ve sayma işleminden önce filtreler; bu nedenle doğrudan COUNT(*) sonucuna koşul uygulayamaz. “İkiden fazla siparişi olan müşteriler” gibi grup sonucuna dayalı bir koşul için HAVING COUNT(*) > 2 kullanılmalıdır.

Doğru seçim, komut adlarını ezberlemekten önce sonuçtaki her satırın neyi temsil ettiğini belirlemekle başlar.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara