我在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
。
答案 0 :(得分:81)
变化:
RANK() OVER (PARTITION BY ContenderNum ORDER BY totals ASC) AS xRank
为:
RANK() OVER (ORDER BY totals DESC) AS xRank
看一下这个例子:
您可能还想查看RANK (Transact-SQL)和DENSE_RANK (Transact-SQL)之间的区别:
RANK (Transact-SQL)
如果两个或更多行绑定排名,则每个绑定的行都会收到相同的排 秩。例如,如果两个顶级销售人员具有相同的SalesYTD 价值,他们都排名第一。销售人员排名第二 SalesYTD排名第三,因为有两行 排名更高。因此,RANK函数并不总是返回 连续整数。
DENSE_RANK (Transact-SQL)
返回结果集分区内的行级别,而不是 排名中的任何差距。行的等级是一加上的数量 排在相关行之前的不同排名。
答案 1 :(得分: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)
你有一个基本上指定分组的分区。
在此示例中,如果按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
答案 2 :(得分:9)
你必须使用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 :(得分:2)
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]
答案 4 :(得分: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
答案 5 :(得分: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
答案 6 :(得分:0)
RANK()
很好,但是它为相同或相似的值分配了相同的等级。而且,如果您需要唯一的排名,那么ROW_NUMBER()就可以解决此问题
ROW_NUMBER() OVER (ORDER BY totals DESC) AS xRank
答案 7 :(得分:-1)
选择T.Tamil,T.English,T.Maths,T.Total,Dense_Rank()Over(由T.Total Desc命令)为Std_Rank From(选择泰米尔语,英语,数学,(泰米尔语+英语+数学)作为学生总数)为T