2009-06-08 32 views
200

Uso de SQL Server, tengo ...SELECT DISTINCT en una columna

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

Quiero

1 FOO-23 Orange 
3 FOO-24 Apple 

Esta consulta no está recibiendo mí no. ¿Cómo puedo SELECCIONAR DISTINCT en una sola columna?

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

¿Podemos suponer que no se preocupan por el sufijo de los datos de columna SKU? Es decir, sólo se preocupan por "foo" y no "FOO-xx" – Kane

+2

¿Cuál es su lógica para elegir ID = 1, SKU = FOO-23 sobre los otros valores? Es fácil crear una consulta que responde specfically ID = 1, pero no para un caso general – gbn

+2

gbn - este es un ejemplo excesivamente simplificado (obviamente). Lo que intento mostrar es un ejemplo que satisface ambos criterios. No hay (y no es necesario) lógica a la que se elige. – mmcglynn

Respuesta

259

Suponiendo que está en SQL Server 2005 o superior, puede utilizar 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

No está utilizando una [CTE] (http://msdn.microsoft.com/en-us/library/ms190766.aspx) en su consulta. Esa es solo una tabla derivada. Pero tienes razón de que * podrías * haber usado un CTE aquí. –

+0

dejar de lado "AS" para Oracle -> ... DONDE COMO SKU '% FOO') una DONDE a.RowNumber = 1 –

12

probar esto:

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

EDITAR
una vez que el OP corregido su producción samle (anteriormente sólo tenía una fila de resultados, todos ahora ha mostrado), esta es la pregunta correcta:

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

iba a 1 esto, porque creo que GROUP BY es el camino correcto a seguir - pero el la ID mínima y el SKU mínimo pueden no pertenecer al mismo registro. Es difícil determinar cuáles son los ID correcto y SKU reportar para un producto determinado. –

34

La solución más simple sería utilizar una subconsulta para encontrar el ID mínimo coincidan con su consulta. En la subconsulta utiliza GROUP BY en lugar de DISTINCT:

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

Prueba esto:

SELECT * FROM [TestData] donde id IN (SELECT MIN DISTINCT (Id) a partir de [TestData] GROUP BY Producto)

+0

que no devuelve ningún resultado. No funciona – DoodleKana

5

Sé que se lo pidieron hace más de 6 años, pero el conocimiento sigue siendo el conocimiento. Esta es una solución diferente a todo lo anterior, ya que tenía que ejecutar el programa bajo 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 
Cuestiones relacionadas