Beschränken Sie die Ergebnisse auf die ersten zwei Rangfolgen

22

In SQL Server 2008 verwende ich RANK() OVER (PARTITION BY Col2 ORDER BY Col3 DESC), um einen Datensatz mit zurückzugeben RANK. Aber ich habe Hunderte von Datensätzen für jede Partition, daher erhalte ich Werte von Rang 1, 2, 3 ... 999. Aber ich will nur bis zu 2 RANKsin jedem PARTITION.

Beispiel:

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

Ich möchte das Ergebnis:

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

Ich möchte nur Rang 1 und 2 in jeder Kategorie. Wie mache ich das?

UB01
quelle

Antworten:

15

Sie können die ursprüngliche Abfrage mithilfe von rank()in eine Unterabfrage einfügen und sie mit einer Abfrage umschließen, die die Ergebnisse filtert.

Betroffen vonTunbridgeWells
quelle
Macht Sinn. Ich wünschte, Microsoft würde es einfacher machen, dh eine Zahl in die RANK-Funktion einfügen. RANK(2) OVER (PARTITION BY Col2 ORDER B Y Col3) AS Top_2_Ranks. Möglicherweise wird es in zukünftigen Versionen passieren. Vielen Dank für die Idee.
UB01
@ UB01: Oder noch besser, es wäre schön, Fensterfunktionen in einer WHEREKlausel zu verwenden.
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
quelle
0

Ich denke, die Möglichkeit, dies in SQL Server zu tun, besteht darin, die Fensterfunktion mit einem gemeinsamen Tabellenausdruck zu kombinieren:

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

Für Teradara können Sie alternativ Folgendes tun:

SELECT 
Subject, 
Name, 
RANK() OVER (PARTITION BY Subject ORDER BY Score DESC) as RN
FROM Table
QUALIFY a.RN <= 2
Dimitar Nentchev
quelle
3
Nun, das mag in Ordnung sein, aber die Frage bezieht sich speziell auf SQL Server.
7.