Limitar resultados às duas primeiras linhas do ranking

22

No SQL Server 2008, estou usando RANK() OVER (PARTITION BY Col2 ORDER BY Col3 DESC)para retornar o conjunto de dados RANK. Mas eu tenho centenas de registros para cada partição, então vou obter valores do ranking 1, 2, 3 ...... 999. Mas eu quero apenas até 2 RANKsem cada PARTITION.

Exemplo:

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

Eu quero que o resultado seja:

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

Eu quero apenas as classificações 1 e 2 em cada categoria. Como eu faço isso?

UB01
fonte

Respostas:

15

Você pode colocar a consulta original rank()em uma subconsulta e agrupá-la com uma consulta que filtre os resultados.

ConcernedOfTunbridgeWells
fonte
Faz sentido. Eu gostaria que a Microsoft tornasse mais simples, ou seja, coloque um número na função RANK. RANK(2) OVER (PARTITION BY Col2 ORDER B Y Col3) AS Top_2_Ranks. Pode ser que isso aconteça em versões futuras. Obrigado pela idéia, no entanto.
UB01
@ UB01: Ou melhor ainda, seria bom usar funções em janelas em uma 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
fonte
0

Eu acho que a maneira de fazer isso no SQL Server é combinar a função de janela com uma expressão de tabela comum:

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
fonte
-1

Para Teradara, você também pode fazer:

SELECT 
Subject, 
Name, 
RANK() OVER (PARTITION BY Subject ORDER BY Score DESC) as RN
FROM Table
QUALIFY a.RN <= 2
Dimitar Nentchev
fonte
3
Bem, pode estar tudo bem, mas a questão é especificamente sobre o SQL Server.
Dezso