如何在SQL Server中使用RANK()

我在使用SQL Server中的RANK()遇到问题。

这是我的代码:

 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 

该查询的结果是:

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

我期望的结果是:

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

我想根据totals对结果进行排名。 如果有相同的值,如181 ,那么两个数字将具有相同的xRank

只是改变

 OVER (PARTITION BY ContenderNum ORDER BY totals ASC) 

 OVER (ORDER BY totals ASC) 

看看这个例子

SQL小提琴演示

您可能还想看看RANK(Transact-SQL)和DENSE_RANK(Transact-SQL)之间的区别。

RANK(Transact-SQL)

如果两个或更多的行绑定一个等级,则每个绑定的行接收相同的等级。 例如,如果两个顶级销售人员具有相同的SalesYTD值,则他们都排名第一。 SalesYTD排名第二的销售人员排名第三,因为有两排排名较高。 因此,RANK函数并不总是返回连续的整数。

DENSE_RANK(Transact-SQL)

返回结果集分区内的行的排名,在排名中没有任何空白。 一行的排名是一个加上有问题的行之前的不同行列的数目。

要回答您的问题标题,“如何在SQL Server中使用Rank()”,这是如何工作的:

我将以这组数据为例:

 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) 

你有一个基本上指定分组的分区。

在本例中,如果按column2进行分区,则rank函数将为column2值组创build排名。 row2 ='SKA'的行的行数会比column2 ='SKB'的行的行数不同,等等。

队伍是这样决定的:每个logging的等级是一个加上在它的分区之前的等级的数量。 只有当您select的字段(分区字段除外)与其之前的字段不同时,排名才会增加。 如果所有select的字段都是相同的,那么行列将会相互配合,并且都将被分配一个值。

知道这一点,如果我们只想从第二列中的每个组中select一个值,我们可以使用这个查询:

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

结果:

 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

你必须使用DENSE_RANK而不是RANK。 唯一的区别是它不会留下空隙。 你也不应该用contender_num进行分区,否则你会在一个单独的组中对每个竞争者进行排名,所以每个人在他们的隔离组中排名第一!

 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 

有关使用StackOverflow的提示,请发布DDL和示例数据,以便人们可以使用更less的时间帮助您!

 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; 

DENSE_RANK()是一个没有差距的等级,即它是“密集的”。

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

RANK() – 它包含排名之间的差距。

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

您已经按ContenderNum分组,不需要再次进行分区。 使用Dense_rank()并按总计descsorting。 简而言之,

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