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
.
sql-server
tsql
Prinz Jea
quelle
quelle
Antworten:
Veränderung:
zu:
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 :
quelle
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
quelle
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;
quelle
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]
quelle
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
quelle
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
quelle
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 Problemquelle
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
quelle