77

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

4

8 回答 8

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)

返回结果集分区内的行排名,排名中没有任何间隙。行的排名是相关行之前的不同排名数的加一。

于 2012-10-05T03:52:15.973 回答
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' 的行的排名不同,依此类推。

排名是这样决定的:每条记录的排名是其分区中位于它之前的排名数量的 1 加。仅当您选择的字段之一(分区字段除外)与之前的字段不同时,排名才会增加。如果所有选定的字段都相同,则排名将平局,并且都将被分配值一。

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

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

于 2013-07-16T14:02:25.783 回答
10

您必须使用 DENSE_RANK 而不是 RANK。唯一的区别是它不会留下空隙。您也不应该按竞争者编号进行分区,否则您会将每个竞争者排名在一个单独的组中,因此每个竞争者在其隔离组中排名第一!

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;
于 2012-10-05T03:53:58.673 回答
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]
于 2016-07-28T11:48:25.843 回答
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
于 2014-08-27T09:17:24.207 回答
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
于 2013-08-20T11:52:39.677 回答
0

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

ROW_NUMBER() OVER (ORDER BY totals DESC) AS xRank
于 2018-08-10T15:56:23.723 回答
-1

Select T.Tamil, T.English, T.Maths, T.Total, Dense_Rank()Over(Order by T.Total Desc) as Std_Rank From (select Tamil,English,Maths,(Tamil+English+Maths) as Total From学生)作为 T

在此处输入图像描述

于 2018-04-23T11:05:53.883 回答