Limite los resultados a las primeras 2 filas de clasificación

22

En SQL Server 2008, estoy usando RANK() OVER (PARTITION BY Col2 ORDER BY Col3 DESC)para devolver el conjunto de datos con RANK. Pero tengo cientos de registros para cada partición, por lo que obtendré valores del rango 1, 2, 3 ... 999. Pero solo quiero hasta 2 RANKsen cada uno PARTITION.

Ejemplo:

ID   Name    Score    Subject
1    Joe      100      Math
2    Jim      99       Math
3    Tim      98       Math
4    Joe      99       History
5    Jim      100      History
6    Tim      89       History
7    Joe      80       Geography
8    Tim      100      Geography
9    Jim      99       Geography

Quiero que el resultado sea:

SELECT Subject, Name, RANK() OVER (PARTITION BY Subject ORDER BY Score DESC)
FROM Table
Subject        Name      Rank
Math           Joe        1
Math           Jim        2
History        Jim        1
History        Joe        2
Geography      Tim        1
Geography      Jim        2

Solo quiero el rango 1 y 2 en cada categoría. ¿Cómo hago esto?

UB01
fuente

Respuestas:

15

Puede colocar la consulta original rank()en una subconsulta y envolverla con una consulta que filtre los resultados.

Preocupado por TunbridgeWells
fuente
Tiene sentido. Deseo que Microsoft lo haga más simple, es decir, ponga un número en la función RANK. RANK(2) OVER (PARTITION BY Col2 ORDER B Y Col3) AS Top_2_Ranks. Puede ser que suceda en futuras versiones. Gracias por la idea sin embargo.
UB01
@ UB01: O mejor aún, sería bueno usar funciones de ventana en una WHEREcláusula.
Jon of All Trades
16
select * from (
SELECT Subject, Name, RANK() OVER (PARTITION BY Subject ORDER BY Score DESC) as RN
FROM Table
) a
where a.RN <= 2
Derek Kromm
fuente
0

Creo que la forma de hacer esto en SQL Server es combinar la función de ventana con una expresión de tabla común:

with cte as (
SELECT Subject, Name, RANK() OVER (PARTITION BY Subject ORDER BY Score DESC) as ordinal
FROM Table
)
select * from cte where ordinal <= 2
josebrwn
fuente
-1

Para Teradara, alternativamente, puede hacer:

SELECT 
Subject, 
Name, 
RANK() OVER (PARTITION BY Subject ORDER BY Score DESC) as RN
FROM Table
QUALIFY a.RN <= 2
Dimitar Nentchev
fuente
3
Bueno, eso podría estar bien, pero la pregunta es específicamente sobre SQL Server.
dezso