Verwendung von RANK () in SQL Server

76

Ich habe ein Problem bei der Verwendung RANK()in SQL Server.

Hier ist mein Code:

SELECT contendernum,
       totals, 
       RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank
FROM (
   SELECT ContenderNum,
          SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
   FROM Cat1GroupImpersonation
   GROUP BY ContenderNum
) AS a

Die Ergebnisse für diese Abfrage sind:

contendernum    totals    xRank
          1       196        1
          2       181        1
          3       192        1
          4       181        1
          5       179        1

Was mein gewünschtes Ergebnis ist:

contendernum    totals    xRank
          1       196        1
          2       181        3
          3       192        2
          4       181        3
          5       179        4

Ich möchte das Ergebnis basierend auf bewerten totals. Wenn es den gleichen Wert wie gibt 181, haben zwei Zahlen den gleichen Wert xRank.

Prinz Jea
quelle
Versuchen Sie Folgendes : docs.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql Vielleicht möchten Sie auch den Unterschied zwischen RANK (Transact-SQL) und DENSE_RANK (Transact-SQL) untersuchen )
Ankursonikajen

Antworten:

85

Veränderung:

RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank

zu:

RANK() OVER (ORDER BY totals DESC) AS xRank

Schauen Sie sich dieses Beispiel an:

SQL Fiddle DEMO

Vielleicht möchten Sie auch den Unterschied zwischen RANK (Transact-SQL) und DENSE_RANK (Transact-SQL) untersuchen :

RANG (Transact-SQL)

Wenn zwei oder mehr Reihen einen Rang bilden, erhält jede gebundene Reihe den gleichen Rang. Wenn beispielsweise die beiden Top-Vertriebsmitarbeiter den gleichen SalesYTD-Wert haben, werden beide als Erste eingestuft. Der Verkäufer mit dem nächsthöheren SalesYTD wird als Nummer drei eingestuft, da zwei Zeilen höher eingestuft sind. Daher gibt die RANK-Funktion nicht immer aufeinanderfolgende Ganzzahlen zurück.

DENSE_RANK (Transact-SQL)

Gibt den Rang der Zeilen innerhalb der Partition einer Ergebnismenge ohne Lücken in der Rangfolge zurück. Der Rang einer Zeile ist eins plus die Anzahl der unterschiedlichen Ränge, die vor der betreffenden Zeile stehen.

Adriaan Stander
quelle
Ich möchte, dass die höchste Summe Nein ist. 1 und der vorletzte auf Platz 2 ... Ihre Antwort hat nicht funktioniert, aber trotzdem danke.
Prinz Jea
Ändern Sie den ASC in DESC wie in der DEMO.
Adriaan Stander
1
Ihr SQL Fiddle DEMO funktioniert nicht mehr. Wahrscheinlich, weil fiddle jetzt SQL Server 2017 und nicht 2008 unterstützt.
Matthieu Cormier
20

Um Ihren Fragentitel "Verwendung von Rank () in SQL Server" zu beantworten, funktioniert dies folgendermaßen:

Ich werde diesen Datensatz als Beispiel verwenden:

create table #tmp
(
  column1 varchar(3),
  column2 varchar(5),
  column3 datetime,
  column4 int
)

insert into #tmp values ('AAA', 'SKA', '2013-02-01 00:00:00', 10)
insert into #tmp values ('AAA', 'SKA', '2013-01-31 00:00:00', 15)
insert into #tmp values ('AAA', 'SKB', '2013-01-31 00:00:00', 20)
insert into #tmp values ('AAA', 'SKB', '2013-01-15 00:00:00', 5)
insert into #tmp values ('AAA', 'SKC', '2013-02-01 00:00:00', 25)

Sie haben eine Partition, die im Grunde die Gruppierung angibt.

Wenn Sie in diesem Beispiel nach Spalte2 partitionieren, erstellt die Rangfunktion Ränge für Gruppen von Spalten2-Werten. Für Zeilen mit Spalte2 = 'SKA' gibt es andere Ränge als für Zeilen mit Spalte2 = 'SKB' usw.

Die Ränge werden wie folgt festgelegt: Der Rang für jeden Datensatz ist eins plus die Anzahl der Ränge, die in seiner Partition davor stehen. Der Rang wird nur erhöht, wenn eines der von Ihnen ausgewählten Felder (außer den partitionierten Feldern) sich von den vorhergehenden unterscheidet. Wenn alle ausgewählten Felder gleich sind, werden die Ränge gleichgesetzt und beiden wird der Wert eins zugewiesen.

Wenn wir dies wissen und nur einen Wert aus jeder Gruppe in Spalte zwei auswählen möchten, können wir diese Abfrage verwenden:

with cte as 
(
  select *, 
  rank() over (partition by column2 
             order by column3) rnk
  from t

) select * from cte where rnk = 1 order by column3;

Ergebnis:

COLUMN1 | COLUMN2   | COLUMN3                           |COLUMN4 | RNK
------------------------------------------------------------------------------
AAA     | SKB   | January, 15 2013 00:00:00+0000    |5   | 1
AAA     | SKA   | January, 31 2013 00:00:00+0000    |15  | 1
AAA     | SKC   | February, 01 2013 00:00:00+0000   |25  | 1

SQL DEMO

Jared Beach
quelle
10

Sie müssen DENSE_RANK anstelle von RANK verwenden. Der einzige Unterschied ist, dass es keine Lücken hinterlässt. Sie sollten auch nicht nach contender_num partitionieren, da Sie sonst jeden Konkurrenten in einer separaten Gruppe einstufen, sodass jeder in seiner getrennten Gruppe den 1. Platz belegt!

SELECT contendernum,totals, DENSE_RANK() OVER (ORDER BY totals desc) AS xRank FROM
(
SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
FROM dbo.Cat1GroupImpersonation
 GROUP BY ContenderNum
) AS a
order by contendernum

Als Hinweis für die Verwendung von StackOverflow veröffentlichen Sie bitte DDL- und Beispieldaten, damit die Benutzer Ihnen helfen können, weniger Zeit zu sparen!

create table Cat1GroupImpersonation (
contendernum int,
criteria1 int,
criteria2 int,
criteria3 int,
criteria4 int);

insert Cat1GroupImpersonation select
1,196,0,0,0 union all select
2,181,0,0,0 union all select
3,192,0,0,0 union all select
4,181,0,0,0 union all select
5,179,0,0,0;
RichardTheKiwi
quelle
3

DENSE_RANK () ist ein Rang ohne Lücken, dh er ist "dicht".

select Name,EmailId,salary,DENSE_RANK() over(order by salary asc) from [dbo].[Employees]

RANK () - Es enthält eine Lücke zwischen dem Rang.

select Name,EmailId,salary,RANK() over(order by salary asc) from [dbo].[Employees]
Debendra Dash
quelle
0

Sie haben bereits nach ContenderNum gruppiert, müssen nicht erneut danach partitionieren. Verwenden Sie Dense_rank () und sortieren Sie nach Summen absteigend. Zusamenfassend,

SELECT contendernum,totals, **DENSE_RANK()** 
OVER (ORDER BY totals **DESC**) 
AS xRank 
FROM
(
   SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
   FROM dbo.Cat1GroupImpersonation
   GROUP BY ContenderNum
) AS a
Ajit
quelle
Wie unterscheidet sich diese Antwort von anderen Antworten?
Noel
@ Ramblin'Man Weil es ganz anders ist.
Sliq
0
SELECT contendernum,totals, RANK() OVER (ORDER BY totals ASC) AS xRank FROM
(
SELECT ContenderNum ,SUM(Criteria1+Criteria2+Criteria3+Criteria4) AS totals
FROM dbo.Cat1GroupImpersonation
 GROUP BY ContenderNum
) AS a
Adi
quelle
0

RANK()ist gut, aber es weist den gleichen Rang für gleiche oder ähnliche Werte zu. Und wenn Sie einen eindeutigen Rang benötigen, löst ROW_NUMBER () dieses Problem

ROW_NUMBER() OVER (ORDER BY totals DESC) AS xRank
Bex
quelle
-1

Wählen Sie T.Tamil, T.English, T.Maths, T.Total, Dense_Rank () Over (Order by T.Total Desc) als Std_Rank From (wählen Sie Tamil, English, Maths, (Tamil + English + Maths) als Total From Student) als T.

Geben Sie hier die Bildbeschreibung ein

Rajenthiran T.
quelle
Wir können drei Themen hinzufügen und den Rang dafür festlegen.
Rajenthiran T
In dieser Abfrage, die für diese Operation nützlich ist, können wir nicht alle Schülerzeichen oder Finanzmittel in jeder Zeile zusammenfassen.
Rajenthiran T