2011-01-11 13 views
54

benzersiz her değer için sadece ilk satırları seçmek için nasıl en Müşteri adreslerinin bir tablo olduğunu varsayalım: TablodaLet bir sütunun

CName   | AddressLine 
------------------------------- 
John Smith  | 123 Nowheresville 
Jane Doe  | 456 Evergreen Terrace 
John Smith  | 999 Somewhereelse 
Joe Bloggs  | 1 Second Ave 

John Smith gibi bir müşteri birden çok adres olabilir. Bu tablo için 'CName' içinde yinelemelerin bulunduğu yalnızca ilk satırı döndürmek için seçme sorgusuna ihtiyacım var. Bu tablo için 3. satır hariç tüm satırları döndürmelidir (ya da 1 - bu iki adresin herhangi biri tamam, ancak yalnızca bir tanesi iade edilebilir). SELECT sorgusuna, sunucunun daha önce sütun değerini daha önce görmüş olup olmadığına göre filtrelemek üzere ekleyebileceğim bir anahtar kelime var mı?

cevap

82

Hangi adresin kullanıldığını umursamıyorsanız çok basit bir cevap.

SELECT 
    CName, MIN(AddressLine) 
FROM 
    MyTable 
GROUP BY 
    CName 

SQL 2K5 + işaretine

SELECT 
    M.CName, M.AddressLine, 
FROM 
    (
    SELECT 
     CName, MIN(Inserted) AS First 
    FROM 
     MyTable 
    GROUP BY 
     CName 
    ) foo 
    JOIN 
    MyTable M ON foo.CName = M.CName AND foo.First = M.Inserted 
+3

MIN BY GROUP BY ile çalışıyor gibi görünüyor. – nuit9

+0

10 sütun seçerken bu şekilde kullanılması amaçlanmamış olabilir. Ayrıca bit tipinde bir sütunu kabul edemez gibi görünüyor. – nuit9

+0

@ nuit9: Tabii ki bit ve 10 sütun ile çalışmaz. Bu gerçeklerden hiçbiri sorunuzda yok. İkinci tekniği veya Ben Thul'un tekniğini kullanırdınız. Özellikle, daha genel olarak nasıl çözüleceğine dair işaretçilerle birlikte, özellikle istediklerinizi cevapladım. – gbn

19

, şöyle bir şey yapabilirsiniz, farklı bir sorguya diyelim ki, bir "takılı" sütunu sonra bu, uygun ilk isterseniz:

;with cte as (
    select CName, AddressLine, 
    rank() over (partition by CName order by AddressLine) as [r] 
    from MyTable 
) 
select CName, AddressLine 
from cte 
where [r] = 1 
+0

Lütfen neyin ne yaptığını açıklayın, bölüm ve [r] – Roberto

+5

Hayır, snarky olmayacak, ancak Wii'yi okuyarak, burada söyleyebileceğim her şeyden daha faydalı olabilirsiniz. Sadece favori arama motoruna "rank fonksiyonu SQL" atmak. Bundan sonra belirli sorularınız varsa bana bildirin! –

9

Satırın satır numarasını almak için row_number()'u kullanabilirsiniz. over komutunu kullanır - partition by yan tümcesi, numaralandırmanın ne zaman yeniden başlatılacağını belirtir ve order by, satır numarasının ne sipariş edileceğini seçer. Sorgunuzun sonuna bir order by eklediyseniz bile, numaralandırma sırasında siparişi over komutunda koruyacaktır.

select * 
from mytable 
where row_number() over(partition by Name order by AddressLine) = 1 
+5

Postgresql'de, WHERE yan tümcesinde pencere işlevlerine izin verilmiyor – ekanna

+1

Bu, MS-SQL için izinli değildir. – Mixxiphoid

+0

'ROW_NUMBER()', Teradata'daki 'Where' maddesinde de çalışmıyor –

0

Öyle gibi row_numer() over(partition by ...) sözdizimi kullanabilirsiniz:

select * from 
(
select * 
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row 
from myTable 
) as a 
where row = 1 

ne yapar o aynı CName görür her seferinde artırır bir karşı olan row adlı bir sütun oluşturur olması ve bu oluşumları AddressLine ile dizinler. where row = 1 yüklenerek, AddressLine alfabetik olarak ilk önce gelen CName arasından seçim yapılabilir. order by, desc ise, o zaman AddressLine alfabetik olarak son CName seçer.

İlgili konular