2009-06-08 12 views
200

Utilizzo di SQL Server, ho ...SELECT DISTINCT su una colonna

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

voglio

1 FOO-23 Orange 
3 FOO-24 Apple 

Questa interrogazione non mi è sempre lì. Come posso selezionare DISTINCT su una sola colonna?

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

Possiamo supporre che non vi interessa circa il suffisso i dati della colonna SKU? I.E., ti interessa solo "FOO-" e non "FOO-xx" – Kane

+2

Qual è la tua logica per la scelta di ID = 1, SKU = FOO-23 sugli altri valori? È facile creare una query che risponda in modo speci fi co per ID = 1 ma non riesce per un caso generale – gbn

+2

gbn - questo è un esempio troppo semplificato (ovviamente). Quello che sto cercando di mostrare è un esempio che soddisfa entrambi i criteri. Non c'è (e non c'è bisogno di essere) logica a cui si è scelto. – mmcglynn

risposta

259

Supponendo che si sia su SQL Server 2005 o versione successiva, è possibile utilizzare un CTE con 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

Non si sta utilizzando un [CTE] (http://msdn.microsoft.com/en-us/library/ms190766.aspx) nella query. Questo è solo un tavolo derivato. Ma hai ragione che * potresti * aver usato un CTE qui. –

+0

omettere "AS" per oracle -> ... WHERE SKU LIKE 'FOO%') a WHERE a.RowNumber = 1 –

12

prova:

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
volta PO corretto sua produzione samle (precedentemente aveva una sola fila risultato, ora è tutto mostrato), questa è la query corretta:

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

Stavo per fare +1 su questo, perché penso che GROUP BY sia la strada giusta da percorrere - ma il l'ID minimo e la SKU minima potrebbero non appartenere allo stesso record. È difficile determinare quali sono ID e SKU corretti da riportare per un determinato PRODOTTO. –

34

La soluzione più semplice sarebbe quella di utilizzare una sottoquery per trovare l'ID minima corrisponde alla tua richiesta. Nella subquery si utilizza GROUP BY invece di DISTINCT:

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

Prova questo:

SELECT * FROM [TestData] WHERE Id IN (SELECT MIN DISTINCT (Id) FROM [TestData] GROUP BY prodotto)

+0

che non restituisce alcun risultato. Non funziona – DoodleKana

5

So che è stato chiesto più di 6 anni fa, ma la conoscenza è ancora conoscenza. Si tratta di una soluzione diversa da tutti al di sopra, come ho dovuto correre sotto 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 
Problemi correlati