SQL之排名窗口函数RANK()、ROW_NUMBER()、DENSE_RANK() 和 NTILE() 的区别(SQL 和 Hive SQL 都支持)

现有一张student 表,表中包含id、uname、age、score 四个字段,如下所示:

该表的数据如下所示:

一、ROW_NUMBER()

1、概念

ROW_NUMBER() 为结果集中的每一行分配一个唯一的连续整数,编号从 1 开始。‌ 该函数按照指定的顺序进行排序,即使存在相同的值,每一行也会获得不同的编号。例如,如果有两个排名为 1 的值,下一个值将会被标记为 3‌

2、示例

对student表中的score列使用ROW_NUMBER()进行排序,排序语句如下;

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  ROW_NUMBER() OVER(ORDER BY s.score desc) as higher_score
FROM student s;

执行结果如下所示:

注意:他一般不能用于排名问题,因为对于相同的分数,排名是不同的。

二、RANK()

1、概念

RANK() 为结果集中的每一行分配一个整数,表示其在排序中的相对位置。‌ 如果存在相同的值,RANK() 会将这些值分配相同的排名,并且下一个排名会跳过相应的数量。例如,如果有两个排名为 1 的值,下一个值将会被标记为 3‌。

2、示例

对student表中的score列使用 RANK() 进行排序,排序语句如下;

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  RANK() OVER(ORDER BY s.score desc) as rank_no
FROM student s;

执行结果如下所示:

三、DENSE_RANK()

1、概念

DENSE_RANK() 与 RANK() 类似,也为相同的值分配相同的排名,但它不会跳过数字。‌ 因此,DENSE_RANK() 的排名是连续的,而 RANK() 的排名是不连续的‌。

2、示例

对student表中的score列使用 DENSE_RANK() 进行排序,排序语句如下;

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  DENSE_RANK() OVER(ORDER BY s.score desc) as dense_rank_no
FROM student s;

执行结果如下所示:

四、NTILE()

1、概念

NTILE()函数是一种窗口函数,用于将每个窗口分区的行分割为从1到至多n的n个桶。

2、原理

ntile函数可以将有序的数据集合平均分配到指定的桶中。如果不能平均分配,较小的桶会分配额外的行,并且各个桶中能放的行数最多相差1。例如,如果桶的数量为4,总共有6行数据,分配结果如下:

桶1:1行、2行

桶2:3行、4行

桶3:5行

桶4:6行

这样确保了每个桶中的数据量尽可能均衡。

3、示例

(1)代码1:

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  NTILE(1) OVER(ORDER BY s.score desc) as ntile_no
FROM student s;

(2)代码1运行结果:

(3)代码2:

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  NTILE(2) OVER(ORDER BY s.score desc) as ntile_no
FROM student s;

(4)代码2运行结果:

(5)代码3:

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  NTILE(3) OVER(ORDER BY s.score desc) as ntile_no
FROM student s;

(6)代码 3运行结果:

(7)代码 4:

bash 复制代码
SELECT 
  s.id,
  s.uname,
  s.age,
  s.score,
  NTILE(4) OVER(ORDER BY s.score desc) as ntile_no
FROM student s;

(8)代码 4运行结果:

相关推荐
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
lzhlizihang2 小时前
python如何使用spark操作hive
hive·python·spark
武子康2 小时前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康2 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
武子康10 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
爱上口袋的天空11 小时前
09 - Clickhouse的SQL操作
数据库·sql·clickhouse
Yang.9913 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
JessieZeng aaa14 小时前
CSV文件数据导入hive
数据仓库·hive·hadoop
王ASC16 小时前
ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值。ojdbc8版本23.2.0.0驱动BUG【已解决】
数据库·sql·oracle
执键行天涯18 小时前
【日常经验】修改大数据量的表字段类型,怎么修改更快
sql