什么时候选择rank()而不是dense_rank()或row_number()

z3yyvxxp  于 2021-04-03  发布在  Hive
关注(0)|答案(2)|浏览(576)

既然我们可以用row_number()来获得分配的行号,如果我们想用dense_rank()来找到每一行的排名,而不跳过分区内的任何数字,为什么我们需要rank()函数,我想不出rank()函数所提供的任何用例是dense_rank()row_number()不能满足的。
有什么用例是rank()最适合的吗?

d7v8vwbk

d7v8vwbk1#

当将RANKDENSE_RANK应用于一个没有连带关系的列时,它们都会产生由ROW_NUMBER生成的相同序列。 RANKDENSE_RANK之间的区别出现在连带关系的情况下,而且很微妙。

SALARY | ROW_NUMBER | RANK | DENSE_RANK
1000   | 1          | 1    | 1
1500   | 2          | 2    | 2
1500   | 3          | 2    | 2
2000   | 4          | 4    | 3
2200   | 5          | 5    | 4
2500   | 6          | 6    | 5
2500   | 7          | 6    | 5
2500   | 8          | 6    | 5
3000   | 9          | 9    | 6

希望你能看到上面的内容,当两个或两个以上的记录出现并列时,"RANK "和 "DENSE_RANK "都会将相同的等级分配给所有具有相同值的记录。然而,它们的不同之处在于,"RANK "会按照 "ROW_NUMBER "系列继续计算等级,而 "DENSE_RANK "则不会,而是按照重复等级后的下一个值继续计算等级。
现在回到你的问题,你是选择RANK还是DENSE_RANK取决于你的要求。例如,如果你要报告获奖者,并且总是需要报告第一名、第二名和第三名,不管每个地方是否有并列,你会使用DENSE_RANK,否则,你会使用RANK,这可能意味着没有第二名或第三名。

kcwpcxri

kcwpcxri2#

下面的例子应该有助于说明两者的区别。(db fiddle link of the example below - https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=cef0a4da7559de657aae332491a9c500)

CREATE TABLE t AS
SELECT 'p' v FROM dual UNION ALL
SELECT 'p'   FROM dual UNION ALL
SELECT 'p'   FROM dual UNION ALL
SELECT 'q'   FROM dual UNION ALL
SELECT 'r'   FROM dual UNION ALL
SELECT 'r'   FROM dual UNION ALL
SELECT 's'   FROM dual UNION ALL
SELECT 't'   FROM dual;

SELECT
  v,
  ROW_NUMBER() OVER (ORDER BY v) row_number,
  RANK()       OVER (ORDER BY v) rank,
  DENSE_RANK() OVER (ORDER BY v) dense_rank
FROM t
ORDER BY v;
The above will yield:

+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| p |          1 |    1 |          1 |
| p |          2 |    1 |          1 |
| p |          3 |    1 |          1 |
| q |          4 |    4 |          2 |
| r |          5 |    5 |          3 |
| r |          6 |    5 |          3 |
| s |          7 |    7 |          4 |
| t |          8 |    8 |          5 |
+---+------------+------+------------+

排名和密级都会分配相同的等级,但是在排名中,平局之后的等级会跳过下一个等级。最后标有粗体的部分是排名和密级之间的唯一区别。
一个很好的类比是想象在你的班级里,最高的总分是由两个学生获得的,所以,第一的位置是并列的,你必须把第一名给他们两个人。但是如果你问dense_rank()函数-它会告诉你第2位,因为它不跳过任何排名,因此在这种情况下,第3位将被授予另一个人,他的总分刚好在第2位的人之后。而如果你的问题是你的第1位只有一个奖,只有一个获奖者:-),那么row_numner()将为你解决这个问题,因为row_numner()将把第1和第2位随机分配给获得最高分的学生(类似于抽签),因此在这种情况下,第3位没有矛盾。
现在来看看rank的使用情况:我知道很多资格考试使用rank()方法(不一定是数据库中的rank函数,而是相同的算法或方法)来筛选学生的数量,因为竞争有时会非常激烈,所以平局并不罕见。所以,在平局的情况下,你必须给两个学生相同的排名,因为如果两个学生的分数相同,你也没办法,但是下一个排名会被跳过,否则座位会被填满。现在,在这种联赛中,你可以使用其他标准,如进球数等来消除季后赛的平局,但在考试的情况下,你肯定不能做重新考试来消除平局。这是个非常实际的案例,以说明这个概念有时是有用的。

相关问题