理解排名函数之间的关系,OVER(),GROUP BY?

时间:2013-01-13 03:05:02

标签: sql sql-server-2008

我的书说 -

1 - 排名函数(如RANK(),DENSE_RANK(),ROW_NUMBER()等)需要一个OVER()子句。

所以,下面的代码是错误的 -

select *, RANK()
from [grant]
order by Amount desc

错误 - 'RANK'附近的语法不正确,预计'OVER'。

如果我在上面的代码中添加RANK()之后的OVER(),我又会收到一个错误。 (错误 - 排名函数“RANK”必须具有ORDER BY子句。)

2 - 然后,我的书补充说“排名函数需要ORDER BY信息在OVER()中显示为参数”。

select *, RANK() OVER(ORDER BY Amount DESC) as GrantRank
from [grant]

我的问题是 -

1 - 为什么我们需要一个带排名功能的OVER()子句? 2 - 为什么我们必须删除order by语句并将其放在OVER()中?

这本书没有解释这些事情背后的逻辑!请帮我理解。

提前致谢。

2 个答案:

答案 0 :(得分:3)

  

为什么我们需要一个带有排名功能的OVER()子句?

需要OVER()子句,以便SQL Server确切地知道您希望如何确定RANK()之类的内容。如果不向SQL Server提供订购标准,您期望RANK()是什么?比赛的胜者是时间最快,时间最慢或名字的名字?

  

为什么我们必须删除order by语句并将其放在OVER()

ORDER BY内添加ORDER BY子句时,无需删除OVER()子句。这些是独立使用的 - 一个用于确定RANK(),另一个用于指定排序。

所以,举例来说,如果你想要返回一个种族的终结者,但是将它们排在最后一个位置,你可能会说:

SELECT 
  name, 
  finish_time, 
  [rank] = RANK() OVER (ORDER BY finish_time) -- fastest first
FROM 
  dbo.race_table
ORDER BY 
  finish_time DESC; -- fastest last

答案 1 :(得分:0)

要了解正在发生的事情,您必须了解RANK函数正在做什么 - 它会根据某些列返回数据的排名。对于那些被绑定的人,你获得相同的排名。因此,如果您想知道授权表中哪一行具有最高金额,您需要按特定列降序排序。

想象一下在任何一项运动中的排名 - 你可以让两支球队并列第一名,排名中的下一支球队将排名第三。这基本上是RANK函数为您做的事情。

这是关于MSDN的有用文章。

此处SQL Fiddle也可能有所帮助。