DISTINCT ile Tekrar Eden Satırları Eleme
Varsayılan olarak SELECT, eşleşen tüm satırları döndürür; tekrar edenler dahil. DISTINCT ise SQLite'a, seçtiğiniz kolonlar bakımından birebir aynı olan satırları tek bir satıra indirgemesini söyler. Böylece her benzersiz kombinasyon sonuçta yalnızca bir kez görünür.
Beş satır girdi, üç satır çıktı. SQLite customer kolonuna baktı, tekrar edenleri eledi ve her benzersiz değer için tek satır döndürdü. Sıralama garanti değil — sıra önemliyse ORDER BY eklemeniz lazım.
DISTINCT Tüm Select Listesine Uygulanır
İşte burası çoğu kişiyi yanıltır. DISTINCT tek bir kolonu seçip onu tekilleştirmez; SELECT'te yazdığınız tüm kolonları birlikte ele alır ve satırın tamamına göre tekrarları ayıklar.
Her benzersiz (customer, country) çifti sonuçta bir kez görünür. Aynı müşteri iki farklı ülkeyle eşleşmişse her iki satır da gelir — SQLite'a göre bunlar yinelenen kayıt değildir.
Diğer kolonları görmezden gelen bir DISTINCT(customer) sözdizimi yoktur. Parantezler kafa karıştırıcı görünebilir ama SELECT DISTINCT(customer), country ifadesi, SELECT DISTINCT customer, country ile birebir aynı şekilde yorumlanır; parantezler sadece bir ifadeyi gruplar. Her müşteri için seçilmiş bir ülkeyle birlikte tek bir satır istiyorsanız, bu iş GROUP BY ve bir toplama (aggregate) fonksiyonuyla yapılır.
SQLite COUNT DISTINCT kullanımı
Sıkça karşılaşılan bir ihtiyaç: bir kolonda kaç tane benzersiz değer var? COUNT(*) satır sayısını, COUNT(col) NULL olmayan değerlerin sayısını, COUNT(DISTINCT col) ise NULL olmayan benzersiz değerlerin sayısını verir.
Beş sipariş, üç farklı müşteri, üç farklı ülke. COUNT(DISTINCT ...), DISTINCT ifadesinin en işe yarayan agregat hâlidir; "kaç farklı şey görünmüş?" sorusunu sorduğunuz her an bu kalıba uzanırsınız.
Şuna dikkat edin: SQLite, COUNT(DISTINCT ...) içinde yalnızca tek bir kolona izin verir. Birden fazla kolonun benzersiz kombinasyonlarını saymak istiyorsanız bir alt sorgu kullanmanız gerekir: SELECT COUNT(*) FROM (SELECT DISTINCT a, b FROM t).
SQLite DISTINCT ve NULL Davranışı
NULL değerinin SQL dünyasında tuhaf bir ünü vardır çünkü NULL = NULL ifadesi TRUE değil, NULL döner. Ama DISTINCT burada özel bir istisna yapar: tekrarları ayıklarken tüm NULL değerlerini birbirine eşit kabul eder.
Üç satır dönüyor: 'ada@example.com', 'dan@example.com' ve tek bir NULL. Üç adet NULL e-posta tek satıra düştü. Aynı kural GROUP BY için de, UNION gibi küme işlemleri için de geçerli — "neden o NULL satırı üç kez yerine bir kez görünüyor?" diye kafa patlatırken hatırlamakta fayda var.
DISTINCT, ORDER BY ve LIMIT'ten Önce Çalışır
Bir SELECT sorgusundaki ifadelerin mantıksal sırası şöyledir: FROM → WHERE → GROUP BY → HAVING → SELECT/DISTINCT → ORDER BY → LIMIT. Yani önce DISTINCT tekrar eden kayıtları ayıklar, ardından ORDER BY kalanları sıralar, en sonunda LIMIT sonucu kırpar.
WHERE dört satırı süzüyor, DISTINCT Boris'in tekrar eden kayıtlarını teke indiriyor, ORDER BY alfabetik sıralıyor, LIMIT da ilk ikisini döndürüyor. Bunu bir kere kafanızda adım adım canlandırmanızı öneririm — sonuçların sıralamasıyla ilgili kafa karışıklıkları, genelde hangi adımın ne zaman çalıştığını unutmaktan kaynaklanır.
SQLite DISTINCT vs GROUP BY karşılaştırması
Sadece tekrar eden kayıtları silmek istiyorsanız, aşağıdaki iki sorgu aynı satırları döndürür:
Sonuç aynı. Fark, sonrasında ne yapabildiğinde ortaya çıkıyor:
DISTINCTsadece "bana benzersiz satırları getir" işine yarar, başka bir şeye değil.GROUP BYise "satırları gruplara ayır ve her grup için bir şey hesapla" demektir —COUNT(*),SUM(amount),MAX(created_at)gibi.
Önce DISTINCT yazıp sonra "aslında müşteri başına toplamı da istiyorum" dediğiniz an, GROUP BY'a geçme zamanı gelmiş demektir:
Müşteri başına tek satır, üstüne de istediğiniz toplamlar. DISTINCT bunu yapamazdı — "grup başına tek satır artı bir toplam" gibi bir şeyi ifade edecek bir mekanizması yok.
Dikkat Etmeniz Gereken Birkaç Nokta
- Performans.
DISTINCTgenelde SQLite'ın tekrarları bulmak için satırları sıralamasını ya da hash'lemesini gerektirir. Büyük sonuç kümelerinde, tekilleştirdiğiniz kolon(lar) üzerinde bir indeks işinizi kolaylaştırır. Geniş bir tablonun her kolonu üzerindeSELECT DISTINCTçekiyorsanız, gerçekten her kolona ihtiyacınız var mı bir düşünün. DISTINCT *pek görülmez. Geçerli bir kullanımdır —SELECT DISTINCT * FROM ttüm satırları baz alarak tekrarları ayıklar — ama tablonuzda bir birincil anahtar varsa zaten her satır benzersizdir, yani işe yaramaz.UNIQUEile karıştırmayın.UNIQUEbir tablo kısıtıdır; tekrar eden değerlerin tabloya en baştan eklenmesini engeller.DISTINCTise sorgu anında çalışan, sonuçtaki tekrarları gizleyen bir filtredir. Farklı araçlar, farklı işler.
Sırada: CASE İfadeleri
SELECT, WHERE, ORDER BY ve DISTINCT ile sonuç satırlarını şekillendirebildiğinizde, bir sonraki adım sorgunun içine koşullu mantık eklemektir. CASE ifadeleri, koşullara göre farklı değerler döndürmenizi sağlar — SQL'in if/else merdiveni gibi düşünebilirsiniz ve sonraki sayfada bunu işleyeceğiz.
Sıkça Sorulan Sorular
SQLite'ta SELECT DISTINCT nasıl çalışır?
SELECT DISTINCT, sonuç kümesindeki tekrar eden satırları temizler. SQLite, SELECT listesindeki tüm kolonları karşılaştırır ve her benzersiz kombinasyon için tek bir satır bırakır. Sıralama olarak WHERE ve JOIN'den sonra, ORDER BY ve LIMIT'ten önce devreye girer.
SQLite'ta DISTINCT'i birden fazla kolonda kullanabilir miyim?
Evet, ama şöyle bir incelik var: DISTINCT her zaman SELECT listesinin tamamına uygulanır, tek bir kolona değil. Örneğin SELECT DISTINCT city, country FROM users size benzersiz (city, country) çiftlerini döner. Diğer kolonları yok sayan bir DISTINCT(city) sözdizimi yoktur; öyle bir şey istiyorsanız GROUP BY ile birlikte bir aggregate fonksiyon kullanmanız gerekir.
SQLite'ta DISTINCT, NULL değerlerini nasıl ele alır?
DISTINCT, tekrar eleme sırasında NULL değerlerini birbirine eşit kabul eder; yani içinde NULL olan birden fazla satır tek bir satıra iner. Bu davranış WHERE koşulundaki = operatöründen farklıdır — orada NULL = NULL sonucu "unknown"dır. DISTINCT, GROUP BY ve UNION için geçerli olan özel bir kuraldır bu.
SQLite'ta DISTINCT ile GROUP BY arasındaki fark nedir?
Sadece tekrarları silmek söz konusuysa SELECT DISTINCT col ile SELECT col FROM t GROUP BY col birebir aynı sonucu üretir. Fark niyettedir: yalnızca benzersiz satırları görmek istediğinizde DISTINCT, gruplara göre COUNT(*) ya da SUM(amount) gibi bir hesaplama yapmak istediğinizde ise GROUP BY tercih edilir.