2009-06-08 12 views
200

pomocą SQL Server, mam ...SELECT DISTINCT na jednej kolumnie

ID SKU PRODUCT 
======================= 
1 FOO-23 Orange 
2 BAR-23 Orange 
3 FOO-24 Apple 
4 FOO-25 Orange 

Chcę

1 FOO-23 Orange 
3 FOO-24 Apple 

To zapytanie nie jest coraz mnie tam. Jak wybrać WYBIERZ DISTINCT na jednej kolumnie?

SELECT 
[ID],[SKU],[PRODUCT] 
FROM [TestData] 
WHERE ([PRODUCT] = 
(SELECT DISTINCT [PRODUCT] FROM [TestData] WHERE ([SKU] LIKE 'FOO-%')) 
ORDER BY [ID] 
+1

możemy założyć, że nie dbają o przyrostek na danych kolumny SKU? I.E. Dbasz tylko o "FOO-" a nie "FOO-xx" – Kane

+2

Jaka jest Twoja logika wyboru ID = 1, SKU = FOO-23 w stosunku do innych wartości? Łatwo jest utworzyć zapytanie, które odpowiada specyficznie dla ID = 1, ale kończy się niepowodzeniem dla ogólnego przypadku: – gbn

+2

gbn - jest to zbyt uproszczony przykład (oczywiście). To, co próbuję pokazać, jest jednym z przykładów, który spełnia oba kryteria. Nie ma (i nie musi być) logiki, do której się wybiera. – mmcglynn

Odpowiedz

259

Zakładając, że korzystasz z programu SQL Server 2005 lub nowszego, możesz użyć CTE z ROW_NUMBER():

SELECT * 
FROM (SELECT ID, SKU, Product, 
       ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY ID) AS RowNumber 
     FROM MyTable 
     WHERE SKU LIKE 'FOO%') AS a 
WHERE a.RowNumber = 1 
+30

Nie używasz [CTE] (http://msdn.microsoft.com/en-us/library/ms190766.aspx) w zapytaniu. To tylko wyprowadzona tabela. Ale masz rację, że mogłaś * użyć * CTE tutaj. –

+0

pomiń "AS" dla oracle -> ... GDZIE SKU LIKE "FOO%") a WHERE a.RowNumber = 1 –

12

spróbuj tego:

SELECT 
    t.* 
    FROM TestData t 
     INNER JOIN (SELECT 
         MIN(ID) as MinID 
         FROM TestData 
         WHERE SKU LIKE 'FOO-%' 
        ) dt ON t.ID=dt.MinID 

EDIT
raz OP skorygować jego wyjście samle (wcześniej miałem tylko jeden wynik wiersz, teraz jest wszystko pokazane), jest to prawidłowe zapytanie:

declare @TestData table (ID int, sku char(6), product varchar(15)) 
insert into @TestData values (1 , 'FOO-23'  ,'Orange') 
insert into @TestData values (2 , 'BAR-23'  ,'Orange') 
insert into @TestData values (3 , 'FOO-24'  ,'Apple') 
insert into @TestData values (4 , 'FOO-25'  ,'Orange') 

--basically the same as @Aaron Alton's answer: 
SELECT 
    dt.ID, dt.SKU, dt.Product 
    FROM (SELECT 
       ID, SKU, Product, ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY ID) AS RowID 
       FROM @TestData 
       WHERE SKU LIKE 'FOO-%' 
     ) AS dt 
    WHERE dt.RowID=1 
    ORDER BY dt.ID 
4
SELECT min (id) AS 'ID', min(sku) AS 'SKU', Product 
    FROM TestData 
    WHERE sku LIKE 'FOO%' -- If you want only the sku that matchs with FOO% 
    GROUP BY product 
    ORDER BY 'ID' 
+3

Mieliśmy +1 to, ponieważ myślę, że GROUP BY jest właściwą drogą - ale minimalny identyfikator i minimalna liczba SKU mogą nie przynależeć do tego samego rekordu. Trudno określić, jaki identyfikator i SKU mają być raportowane dla danego PRODUKTU. –

34

Najprostszym rozwiązaniem byłoby użycie podzapytania do znajdowania minimalnego identyfikator pasujący do zapytania. W podzapytaniu użyć GROUP BY zamiast DISTINCT:

SELECT * FROM [TestData] WHERE [ID] IN (
    SELECT MIN([ID]) FROM [TestData] 
    WHERE [SKU] LIKE 'FOO-%' 
    GROUP BY [PRODUCT] 
) 
0

Spróbuj:

select * from [testdata] WHERE id IN (SELECT DISTINCT MIN (ID) FROM [testdata] GROUP BY Produktu)

+0

, który nie zwraca wyniku. Nie działa – DoodleKana

5

Wiem, że pytano mnie o to ponad 6 lat temu, ale wiedza nadal jest wiedzą. Jest inne rozwiązanie niż wszystkie powyżej, jak miałem go uruchomić w ramach programu SQL Server 2000:

DECLARE @TestData TABLE([ID] int, [SKU] char(6), [Product] varchar(15)) 
INSERT INTO @TestData values (1 ,'FOO-23', 'Orange') 
INSERT INTO @TestData values (2 ,'BAR-23', 'Orange') 
INSERT INTO @TestData values (3 ,'FOO-24', 'Apple') 
INSERT INTO @TestData values (4 ,'FOO-25', 'Orange') 

SELECT DISTINCT [ID] = (SELECT TOP 1 [ID] FROM @TestData Y WHERE Y.[Product] = X.[Product]) 
       ,[SKU]= (SELECT TOP 1 [SKU] FROM @TestData Y WHERE Y.[Product] = X.[Product]) 
       ,[PRODUCT] 
      FROM @TestData X