如何在SQL Server中使用RANK()

Pri*_*Jea 72 t-sql sql-server

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
Run Code Online (Sandbox Code Playgroud)

该查询的结果是:

contendernum    totals    xRank
          1       196        1
          2       181        1
          3       192        1
          4       181        1
          5       179        1
Run Code Online (Sandbox Code Playgroud)

我想要的结果是什么:

contendernum    totals    xRank
          1       196        1
          2       181        3
          3       192        2
          4       181        3
          5       179        4
Run Code Online (Sandbox Code Playgroud)

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

Adr*_*der 84

更改:

RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank
Run Code Online (Sandbox Code Playgroud)

至:

RANK() OVER (ORDER BY totals DESC) AS xRank
Run Code Online (Sandbox Code Playgroud)

看看这个例子:

SQL Fiddle DEMO

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

RANK(Transact-SQL)

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

DENSE_RANK(Transact-SQL)

返回结果集分区中的行级别,排名中没有任何间隙.行的等级是一行加上有关行之前的不同等级的数量.


Jar*_*ach 17

要回答你的问题标题,"如何在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)
Run Code Online (Sandbox Code Playgroud)

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

在此示例中,如果按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;
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

SQL DEMO


Ric*_*iwi 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
Run Code Online (Sandbox Code Playgroud)

有关使用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;
Run Code Online (Sandbox Code Playgroud)