SQL'de benzersiz kayıtları çıkarmak, kuruluşların çok boyutlu verilerin depolanmasına geçiş yapmasıyla kritik bir görev haline geldi. Bazen birden fazla sütunun kombinasyonuna göre tekrarlanan satırları kaldırmak, bazen ise yalnızca bir anahtara göre benzersiz satırları çıkarmak gerekebilir.
Sorunun Tarihçesi:
İlk SQL sürümleri yalnızca DISTINCT'i kopyaları filtrelemek için sundu. Daha sonra, benzersiz değer setlerine göre toplama yapmak için GROUP BY gibi yapısal teknikler ve ROW_NUMBER() gibi pencere işlevleri ortaya çıktı. Bu işlevler, daha esnek kopya yönetimi senaryoları için kullanılabilir, örneğin: "son" veya "ilk" kaydı çıkarma.
Problem:
DISTINCT, SELECT seviyesinde yalnızca alanlar grubuna göre çalışırken, GROUP BY toplama gerektirir. Pencere işlevleri, daha gelişmiş bir mantık sunar, ancak satır seçim sırasını iyi düşünmeden kullanıldığında sık sık hatalara yol açar. Geliştiriciler bu yaklaşımları sıklıkla karıştırır; bu hatalar yanılgılı sonuçlara neden olur.
Çözüm:
Kod Örneği:
Her müşteri için siparişlerin son kaydını almak:
WITH OrdersRank AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) as rn FROM Orders ) SELECT * FROM OrdersRank WHERE rn = 1;
Anahtar özellikler:
DISTINCT'i GROUP BY olmadan toplama işlevleri ile kullanmak mümkün mü?
Hayır, toplama işlevleri gruplamayı gerektirir, aksi takdirde sözdizim hatası oluşur.
SELECT COUNT(DISTINCT CustomerID) -- doğru SELECT SUM(Amount), DISTINCT CustomerID -- hata!
GROUP BY'da SELECT'deki tüm gruplama dışındaki alanları belirtmezseniz ne olur?
Bu, çoğu DBMS'de hata verecektir: SELECT'deki tüm alanlar, toplama olanlar haricinde, GROUP BY'da belirtilmelidir.
Pencere işlevlerini kullanarak alt sorgu olmadan kopyalar "kaldırılabilir" mi?
Hayır: ROW_NUMBER()'ı bir SELECT içinde kullanmak otomatik olarak "tekrarı" filtrelemez; istenen satırları seçmek için dış bir sorgu gereklidir.
20 milyon satırlık bir tablo için tüm sütunlar üzerine DISTINCT seçildi: sorgu saatlerce çalıştı, sonuç — zaman aşımı veya veritabanı performansında düşüş.
Artıları:
Eksileri:
Pencere işlevleri kullanıldı: yalnızca milisaniyeler içinde her müşteri için gereken son kaydı aldık; önceki ve tekrar eden kayıtlar yüklenmedi.
Artıları:
Eksileri: