博客 SQL中常用的窗口函数(排序函数)-row_number/rank/dense_rank/ntile

SQL中常用的窗口函数(排序函数)-row_number/rank/dense_rank/ntile

   数栈君   发表于 2023-08-23 09:55  244  0

总结四个函数的特点:

row_number():连续不重复;1234567
rank() :重复不连续;1222567
dense_rank():重复且连续;1222345
ntile():平均分组;1122334

一、函数介绍

SQL Server中的排序函数有四个:row_number(),rank(),dense_rank()及ntile()函数;

1.row_number()函数

特点: row_number()函数可以为每条记录添加递增的顺序数值序号,即使值完全相同也依次递增序号,不会重复。

语法:

ROW_NUMBER() OVER (
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

PARTITION BY子句将结果集划分为分区。 ROW_NUMBER()函数分别应用于每个分区,并重新初始化每个分区的行号。PARTITION BY子句是可选的。如果未指定,ROW_NUMBER()函数会将整个结果集视为单个分区。
ORDER BY子句定义结果集的每个分区中的行的逻辑顺序。 ORDER BY子句是必需的,因为ROW_NUMBER()函数对顺序敏感。

2.rank()函数

特点: rank()函数也是返回每条记录的排名序号,但当值相同时,序号也将相同,同时跳跃排序(比如两个第一名后面是第三名)。

语法:

RANK() OVER (
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

PARTITION BY子句划分应用该函数的结果集分区的行。
ORDER BY子句指定应用该函数每个分区中行的逻辑排序顺序。

3.dense_rank()函数

特点: dense_rank()函数进行排序时,也会将值相同的数据赋予同一个序号,但与rank()函数不同的是,dense_rank()函数为连续排序(比如两个第一名后面是第二名)。

语法:

DENSE_RANK() OVER (
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

dense_rank()函数以ORDER BY子句定义的指定顺序应用于PARTITION BY子句定义的每个分区的行。它会在划分分区边界时重置等级。
PARITION BY子句是可选的。如果省略它,该函数会将整个结果集视为单个分区。

4.ntile(n)函数

特点: ntile(n)函数会将数据分为n组,自动进行分组 (每组数量大致相等,若无法均分为n组,则每组的记录数不能大于它上一组的记录数),每组将会分配同一个序号(组号为1-n)。

语法:

NTILE(integer_expression) OVER (
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

integer_expression 为数据行划分的组数。
PARTITION BY子句将结果集的行分配到应用了NTILE()函数的分区中。
ORDER BY子句指定应用NTILE()的每个分区中行的逻辑顺序。

二、 应用实例

●row_number()函数

将所有数据按照score排名
select row_number()over(order by SCORE) as num,sc.* from sc

结果:
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/877ed2bbf478a6ca7b424be034c7b7b4..png
  
可以看到,score相同的数据行,排序依旧递增。

另外,可以使用partition by为数据进行分组排序
例如,按照CNO分组,将score排序

select row_number()over(partition by CNO order by SCORE) as num,sc.* from sc
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/3041705d0ea5512391c3b85aa7464084..png
  


●rank()函数

将所有数据按照score排名
select rank()over(order by SCORE) as num,sc.* from sc

结果
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/faaecfd3ddd77ed5d63cff1435a75c8e..png
  
可以看到,score相同的数据行,排序相同。并且为跳跃排序(五个9后面是14)。

partition by使用方法相同,不再模拟。

●dense_rank()函数

将所有数据按照score排名
select dense_rank()over(order by SCORE) as num,sc.* from sc

结果
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/e33619454874072aad595956bd1ea8b3..png
  
可以看到,score相同的数据行,排序相同。但为顺序排序(五个9后面仍是10)。
PS:
dense_rank()函数还有个用处,就是将一组内的数据分为同一个序号,并按组递增排序。这样可以获得groupby的num值,对于只有值,没有ID的数据,比较有用。
例如:按照CNO分组排序

select dense_rank()over(order by CNO ) as num,sc.* from sc

结果:
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/579b22e68251f163ca27eb9835b23a98..png
  

●ntile()函数

将所有数据按照score排序,并分为4组
select ntile(4)over(order by SCORE ) as num,sc.* from sc

结果
http://dtstack-static.oss-cn-hangzhou.aliyuncs.com/2021bbs/files_user1/article/c42940c23298bbd307ca73e388871507..png
  





免责申明:


本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!

《数据治理行业实践白皮书》下载地址:https://fs80.cn/4w2atu

《数栈V6.0产品白皮书》下载地址:
https://fs80.cn/cw0iw1

想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:
https://www.dtstack.com/?src=bbs

同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术群」,交流最新开源技术信息,群号码:30537511,项目地址:
https://github.com/DTStack

0条评论
社区公告
  • 大数据领域最专业的产品&技术交流社区,专注于探讨与分享大数据领域有趣又火热的信息,专业又专注的数据人园地

最新活动更多
微信扫码获取数字化转型资料
钉钉扫码加入技术交流群