如何在SQL Server中使用RANK()


76

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

这是我的代码:

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


试试看:docs.microsoft.com/zh-cn/sql/t-sql/functions/rank-transact-sql您可能还想看看RANK(Transact-SQL)和DENSE_RANK(Transact-SQL)之间的区别)
Ankursonikajen

Answers:


85

更改:

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

至:

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

看一下这个例子:

SQL小提琴演示

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

排名(Transact-SQL)

如果有两个或更多行并列,则每个并列的行都将获得相同的列。例如,如果两个最高销售人员的SalesYTD值相同,则他们都将排名第一。SalesYTD排名第二高的销售人员排名第三,因为有两行排名较高。因此,RANK函数并不总是返回连续的整数。

DENSE_RANK(Transact-SQL)

返回结果集分区中的行的排名,排名中没有任何空白。行的等级等于该行之前的不同等级的数量加上一个。


我希望最高的总数为否。1位居第二,第二位居第二位...您的答案不起作用,但仍要感谢。
耶阿亲王

像在DEMO中一样,将ASC更改为DESC。
Adriaan Stander

1
您的SQL Fiddle DEMO不再起作用。大概是因为小提琴现在支持SQL服务器2017年和2008年没有
马蒂厄·科米尔

20

要回答您的问题标题“如何在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值的组创建等级。column2 ='SKA'的行与column2 ='SKB'的行会有不同的排名,依此类推。

排名是这样确定的:每个记录的排名是一个加在其分区之前的排名数。仅当您选择的一个字段(分区字段除外)与之前的字段不同时,排名才会增加。如果所有选定字段都相同,则等级将平局,并且两个值都将分配一个。

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

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


10

您必须使用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和示例数据,以便人们可以用更少的时间帮助您!

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;

3

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]

0

您已经按ContenderNum进行了分组,无需再次对其进行分区。使用Dense_rank()并按合计desc排序。简而言之,

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

这个答案与其他答案有何不同?
Noel

@ Ramblin'Man因为完全不同。
Sliq 2013年

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

0

RANK()很好,但是它为相同或相似的值分配了相同的等级。如果您需要唯一的排名,那么ROW_NUMBER()就可以解决此问题

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

-1

选择T.Tamil,T.English,T.Maths,T.Total,Dense_Rank()Over(按T.Total Desc排序)作为Std_Rank From(选择Tamil,English,Maths,(Tamil + English + Maths)作为总计来自学生)作为T

在此处输入图片说明


我们可以添加三个主题并为此设置等级。
Rajenthiran T

我们无法将所有学生分数或任何与财务相关的财务信息进行逐行总计,在此查询中对该操作有用。
Rajenthiran T
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.