sql中row-ag捕鱼王app官网

sql中row_number()、rank()和dense_rank() 函数的区别

作者:迹忆客 最近更新:2023/02/01 浏览次数:

尽管这三个都是 sql 中的排名函数,在 microsoft sql server 中也称为 window 函数,但是当在排名上有联系时,即重复记录,rank()dense_rank()row_number() 之间的区别就会出现。 例如,如果按薪水对员工进行排名,那么薪水相同的两名员工的排名是多少? 这取决于使用的排名函数,例如 row_numberrankdense_rank

row_number() 函数总是生成一个唯一的排名,即使有重复的记录,即如果 order by 子句不能区分两行,它仍然会给他们不同的排名,尽管哪个记录会出现在前面或后面是随机决定的,就像我们的示例 2 员工 shanerick 的薪水相同,并且排号为 4 和 5,这是随机的,如果我们再次运行,shane 可能会排在第 5 位。

rank()dense_rank() 将对无法通过 order by 子句区分的行给予相同的排名,但 dense_rank 将始终生成连续的排名序列,如 (1,2,3,...),而 rank () 会在相同排名的两行或更多行后留下空缺(想想“奥运会”:如果两个运动员获得金牌,就没有第二名,只有第三名)。

令人惊讶的是,所有这些函数在 microsoft sql server 和 oracle 中的行为都相似,至少在高层是这样,所以如果你在 mssql 中使用过它们,你也可以在 oracle 11g 或其他版本上使用它。


用于构建模式的 sql

下面是用于创建表并向其中插入一些数据以用于演示目的的 sql:

if object_id( 'tempdb..#employee' ) is not null drop table #employee; 
create table #employee (name varchar(10), salary int);
insert into #employee values ('rick', 3000);
insert into #employee values ('john', 4000);
insert into #employee values ('shane', 3000);
insert into #employee values ('peter', 5000);
insert into #employee values ('jackob', 7000);
insert into #employee values ('sid', 1000);

你可以看到我们包括了两名薪水相同的员工,即 shane 和 rick,只是为了演示 sql server 中 row_numberrankdense_rank 窗口函数之间的差异,当排名相同时这一点很明显。

row number vs rank vs dense_rank sql


row_number() 示例

它总是为每一行生成一个唯一的值,即使它们相同并且 order by 子句无法区分它们。 这就是为什么它被用来解决像我们之前看到的第二高薪水或第 n 高薪水这样的问题。

在下面的示例中,我们有两名薪水相同的员工,即使我们在薪水列上生成了行号,它也会为这两名薪水相同的员工生成不同的行号。

select e.*, row_number() over (order by salary desc) row_number from #employee e 
result:
name salary row_number
jackob 7000 1
peter 5000 2
john 4000 3
shane 3000 4
rick 3000 5
sid 1000 6

你可以在这个例子中看到,我们根据员工的薪水对员工进行排名,即使他们的薪水相同,他们每个人都有一个独特的排名。 shanerick 的薪水相同,均为 3000,但他们分别排在第 4 和第 5 位。 值得注意的是,在平局的情况下,排名是随机分配的。


rank() 示例

rank() 函数会将相同的排名分配给相同的值,即不能通过 order by 区分的值。 此外,下一个不同的等级不会从紧接的下一个数字开始,但会有一个差距,即如果第 4 名和第 5 名员工的薪水相同,那么他们将拥有相同的等级 4,而薪水不同的第 6 名员工将有一个新的 排名 6。

这是阐明这一点的示例:

select e.*, rank() over (order by salary desc) rank from #employee e
result:
name salary rank 
jackob 7000 1 
peter 5000 2 
john 4000 3 
shane 3000 4 
rick 3000 4 
sid 1000 6

你可以看到 shanerick 都排在第 4 位,但是 sid 排在第 6 位,而不是第 5 位,因为它保持了原来的顺序。


dense_rank() 示例

dense_rank 函数类似于 rank() 窗口函数,即相同的值将被分配相同的等级,但下一个不同的值将具有比前一个等级高一个的等级,即如果第 4 名和第 5 名员工具有相同的等级 salary 那么他们将具有相同的等级,但是具有不同薪水的第 6 名员工将具有等级 5,这与 rank() 函数的等级 6 不同。 在 dense_rank() 的情况下,排名不会有差距,如下例所示:

select e.*, dense_rank() over (order by salary desc) dense_rank from #employee e 
result:
name salary dense_rank 
jackob 7000 1 
peter 5000 2 
john 4000 3 
shane 3000 4 
rick 3000 4 
sid 1000 5

我们可以看到 shanerick 的排名相同,都是第 4 名,但 sid 现在排名第 5 名,这与我们在前面的示例中使用 rank() 函数时的第 6 名不同。


row_number 与 rank 与 dense_rank 之间的区别

正如我所说,当存在重复记录时,rankrow_numberdense_rank 之间的差异是可见的。 因为在我们所有的例子中,我们都是根据薪水对记录进行排名,如果两条记录的薪水相同,那么我们会注意到这三个排名函数之间的区别。

row_number 给出了连续的数字,而 rankdense_rank 给出了相同的重复排名,但是排名中的下一个数字是按照连续的顺序排列的,所以你会看到一个跳跃,但在 dense_rank 中排名没有任何差距。

select e.*,
row_number() over (order by salary desc) row_number,
rank() over (order by salary desc) rank,
dense_rank() over (order by salary desc) as dense_rank
from #employee e

这里的输出清楚地显示了 rank()dense_rank() 函数生成的排名差异。 这将消除大家对 rankdesnse_rankrow_nubmer 函数的疑虑。

difference between row_number vs rank vs dense_rank in sql

我们可以看到员工 shanerick 的薪水相同,均为 3000,因此当我们使用 rank()dense_rank() 时,他们的排名相同,但下一个排名是 6,这是根据使用 rank() 的连续排名和 5 当我们 使用 dense_rank()row_number() 不会打破联系,并且始终为每条记录提供唯一编号。

顺便说一句,我在 oracle 11g r2 和 oracle 12c 上运行了所有三个 sql 查询,结果相同。 因此,似乎 oracle 和 sql server 都支持这些功能,并且它们的行为相同。

这就是 sql server 中 row_number()rank()dense_rank() 函数之间的区别。 正如我所说,差异归结为关系发生的时间。 在平局的情况下,row_number() 会给出唯一的行号,rank 会给出相同的排名,但是下一个不同的rank不会按顺序,会有差距。

dense_rank 的情况下,并列中的两行将具有相同的排名并且不会有差距。 下一个不同的等级将按顺序排列。

上一篇:

下一篇:sql查询中如何连接三张表

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 mysql 中声明和使用变量

发布时间:2024/03/26 浏览次数:115 分类:mysql

当你需要在 mysql 中的脚本中存储单个值时,最好的方法是使用变量。变量有不同的种类,有必要知道何时以及如何使用每种类型。

发布时间:2024/03/26 浏览次数:176 分类:mysql

本教程演示了如何在 mysql 中重置自动增量。

在 mysql 中实现刷新权限

发布时间:2024/03/26 浏览次数:211 分类:mysql

本教程介绍了 mysql 中的刷新权限命令,用于刷新授权表并影响允许的更改。

在 mysql 中设置时区

发布时间:2024/03/26 浏览次数:93 分类:mysql

在本教程中,我们将学习如何在 mysql 服务器中更改时区。

发布时间:2024/03/26 浏览次数:199 分类:mysql

本教程演示如何在 mysql 中转换为整数。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便
网站地图