2011-03-31 19 views
17

Si tengo una tabla llamada [Parte] con columnas [Idpart], [IDNumber] y [Longitud] y los datos:SQL SELECT DISTINCT Top 2

[PartID] [IDNumber] [Length] 
1   Test1  50 
2   Test1  60 
3   Test2  50 
4   Test3  70 

¿Cómo puedo seleccionar sólo los mejores 2 registros con un IDNumber distinto? Después de buscar un poco, no he podido encontrar una consulta que haga lo que quiero. Me gustaría que los resultados de este aspecto:

[PartID] [IDNumber] [Length] 
1   Test1  50 
3   Test2  50 

Lo que tengo ahora:

Select distinct top 2 
     [PartID], 
     [IDNumber], 
     [Length] 
from 
    [Part] 

para aclarar que el Idpart es en realidad un GUID. Pensé que escribir el GUID para cada registro se estaba metiendo un poco en mis datos de ejemplo.

+2

Top 2 por qué? ** No hay un orden predeterminado en SQL. ** – JNK

+0

¿Desea los grupos TOP 2 (por [IDNumber]) ordenados por PartId y luego desde estos dos grupos desea el registro superior único? –

+0

Top 2 ordenando por 'PartID ASC'? – Lamak

Respuesta

41
SELECT DISTINCT TOP 2 PartId, IdNumber, Length 
FROM 
( SELECT PartId, IdNumber, Length, ROW_NUMBER() over(partition by IdNumber order by Length) Orden 
    FROM [Ayuda] 
) A 
WHERE A.Orden = 1 
ORDER BY Length 
3
SELECT TOP 2 b.* 
FROM (SELECT idnumber, 
       MIN(partid) partid 
     FROM part 
     GROUP BY idnumber) a 
     JOIN part b 
     ON a.partid = b.partid 
ORDER BY b.partid 
+0

+1 Me pregunto si hay una forma de hacerlo con solo un escaneo parcial. –

+0

@Martin - Ahora que el operador agregó que está usando SQL Server 2005, tal vez pueda probar la respuesta de @Longha y ver si eso evita un escaneo adicional. – Lamak

+0

¡Gracias por la respuesta! Olvidé aclarar, pero mi campo PartID es en realidad un GUID. Lo siento por eso. Cuando estaba escribiendo los datos de muestra, pensé que era un poco complicado escribir todo el GUID. – MisterXero

1

No ha mencionado qué fila seleccionar para el IDNumber duplicado. Según su ejemplo, suponiendo que se utilizará Min PartID, puede usar la siguiente consulta. Tendría que ser ajustado un poco.

Select Top 2 
    P.* 
From 
    [Part] P 
Inner Join 
    (
     Select 
      [IDNumber] 
      ,Min([PartID]) As MinPartID, 
     From 
      [Part] 
     Group By 
      [IDNumber] 
    ) T 
On 
    P.PartID = T.MinPartID 
    And 
    P.IDNumber = T.IDNumber -- May not be needed is PartID is primary Key 
Order By 
    P.[PartID] 
    ,P.[IDNumber] 
Cuestiones relacionadas