T-SQL sorgularında veri çekilecek tabloda, kayıtları benzersizliğe zorlayan anahtar sütun olsa bile dönen sonuçta illaki yinelenen satırlar olacaktır. Bu durum, genellikle tablodaki sadece birkaç sütunu çektiğimizde böyle olmaktadır. Bu bölümde DISTINCT ifadesi kullanarak dönen sonuç içerisindeki yinelenen kayıtları nasıl yok edileceğini öğreneceğiz.

SQL Kümeler ve Yinelenen Satırlar

İlişkisel veri tabanları teorisinde, bir tabloda benzersiz satırlara çağrı yapılır. Pratikte ise, T-SQL sorgularından dönen sonuçlar aslında doğru sonuç kümeleri değildir. Primary key kullanan bir tabloya sorgu atıldığında bile dönen satırların benzersiz olması garanti edilmez. Ayrıca satırlar belli bir sırada döndürülmeyecektir. Sıralı hale getirmek için ise ORDER BY ifadesi kullanılır.

SELECT ifadesinin, aslında varsayılan olarak biz koymasak bile önünde her zaman ALL tümcesi bulunur, bu sebeple sorgu sonucunda yinelenen değerlerin olabildiğini görürüz.

Örneğin ülke adlarını Sales.Customers tablosundan döndüren bir sorguyu düşünün:

SELECT country
FROM Sales.Customers;

Aşağıda dönen sonuçta yinelenen satırların olduğunu görürüz. Anlaşılırlık açısından, diyelim ki sorgu sonucunda yinelenen satır bulunduran 10 kayıt dönmüş olsun. Sonuç tablosuna şöyle bir baktığımız zaman kaç farklı ülke varmış diye hesaplamaya çalışır fakat cevabını geç veririz.

country
--------------------
Germany
Mexico
Mexico
UK
Sweden
Germany
Germany
France
UK 
Austria
Brazil
Spain
France
Sweden
…
Germany
France
Finland
Poland
 (91 rows(s) affected) 

Dönen sonuçta tekrarlı kayıtların olmasının nedeni, varsayılan olarak SELECT ifadesinin önünde varsayılan olarak gizli bir ALL ifadesi bulunmasıdır:

SELECT ALL country
FROM Sales.Customers;

Bu arada sorgumuz Sales.Customers tablosundaki her satırı döndürmektedir, ancak yalnızca ülke sütunu belirtildiği için 91 sütunun arasından sadece bu sütun dönmektedir.

DISTINCT İfadesi

Varsayılan SELECT ALL tümcesinde ALL yerine DISTINCT koyduğumuzda oluşacak olan tümce SELECT DISTINCT olur. Yeni oluşan ifade, sonuç kümesinin yalnızca benzersiz satırlar içermesi gerektiği şekilde sonucu döndürür. Bununla birlikte DISTINCT tümcesi sadece SELECT ifadesi tarafından döndürülen sütunlar üzerinde çalışır. Tablodaki diğer benzersiz sütunlar zaten hazır olduğu için dikkate almaz.

İşlemlerin mantıksal sırası sonucu olarak, WHERE, HAVING ve GROUP BY tümceleri tarafından işlenmiş olan satırlarda bulunan yinelenen kayıtlar da DISTINCT operatörü yardımıyla kaldırılır.

Örnek olarak Sales.Customers tablosunda yinelenen değerleri ortadan kaldırmak için ALL varsayılan deyimini DISTINCT ile değiştirebilirsiniz:

SELECT DISTINCT country
FROM Sales.Customers;

Böylece istenen sonuçlar dönecektir. Sonuçlar sıralı dönmüş halde, fakat daha önce de söylendiği üzere SQL Server tarafından her zaman bu şekilde döneceğinin garantisi yoktur. Aşağıda sorgudan dönen sonuç kümesi, her benzersiz çıktı satırı örneğini içermektedir:

country
--------
Argentina
Austria
Belgium
Brazil
Canada
Denmark 
Finland
France
Germany
Ireland
Italy
Mexico
Norway
Poland
Portugal
Spain
Sweden
Switzerland
UK
USA
Venezuela
 (21 row(s) affected) 

Not: İlerleyen bölümlerde yinelenen değerleri filtrelemek için ek yöntemler göreceğiz. Bunları öğrendikten sonra, SELECT DISTINCT ifadesi ve diğer filtreleme yöntemlerinin performans maliyetlerini karşılaştırabilirsiniz.

SELECT DISTINCT Syntax’ı
SELECT DISTINCT <sütun_listesi>
FROM <tablo_veya_view_ismi>

DISTINCT ifadesi, SELECT tarafından dönen sonuç kümesinde bulunan satırlar üzerinde işlem yapar. Bu nedenle, benzersiz sütun değerleri yalnızca SELECT DISTINCT tarafından döndürülmektedir.

Örneğin, aşağıdaki verileri içeren bir tabloya sorgu attığımızda yalnızca dört çeşit isim ve dört çeşit soyisim olduğunu görüyoruz.

SELECT firstname, lastname
FROM Sales.Customers;

Sorgudan alınan sonuç:

firstname lastname
------------ -----------------
Sara Davis
Don Funk
Sara Lew
Don Davis
Judy Lew
Judy Funk
Yael Peled 

Ancak, her iki sütuna bir SELECT DISTINCT sorgusu attığımızda bu durumda yedi çalışan kaydının olduğu iki sütunun da tüm benzersiz kombinasyonlarını alacaktır.

Sadece benzersiz isimleri çekmek için de firstname sütununa bir SELECT DISTINCT sorgusu atmamız yeterli olacaktır:

SELECT DISTINCT firstname
FROM Sales.Customers;

Sorgu sonucu:

firstname
---------------------
Don
Judy
Sara
Yael
 (4 row(s) affected) 

Bu tür sorgular tasarlamanın zor tarafı, bir sütundan farklı bir değer listesi almanız gerekirken diğerlerinden de ek öznitelikleri (sütunlar) görüntülemek isteyebilirsiniz. Sonraki bölümlerde benzersiz kayıtları görüntülemenin ve bilgi işlemenin bir yolu olan DISTINCT ve GROUP BY ifadelerinin ikisi birlikte nasıl kullanıldığını göreceksiniz.