rank,dense_rank,row_number使用和区别

rank,dense_rank,row_number区别

一:语法(用法):
     rank() over([partition by col1] order by col2)
     dense_rank() over([partition by col1] order by col2)
     row_number() over([partition by col1] order by col2)
     其中[partition by col1]可省略。


二:区别
    三个分析函数都是按照col1分组内从1开始排序
   
    row_number() 是没有重复值的排序(即使两天记录相等也是不重复的),可以利用它来实现分页
    dense_rank() 是连续排序,两个第二名仍然跟着第三名
    rank()       是跳跃拍学,两个第二名下来就是第四名
   
    理论就不多讲了,看了案例,一下就明白了
   
SQL> create table t(
  2   name varchar2(10),
  3   score number(3));
 
Table created
 
SQL> insert into t(name,score)
  2   select '语文',60 from dual union all
  3   select '语文',90 from dual union all
  4   select '语文',80 from dual union all
  5   select '语文',80 from dual union all
  6   select '数学',67 from dual union all
  7   select '数学',77 from dual union all
  8   select '数学',78 from dual union all
  9   select '数学',88 from dual union all
 10   select '数学',99 from dual union all
 11   select '语文',70 from dual
 12  /
 
10 rows inserted
 
SQL> select * from t;
 
NAME       SCORE
---------- -----
语文          60
语文          90
语文          80
语文          80
数学          67
数学          77
数学          78
数学          88
数学          99
语文          70
 
10 rows selected
 
SQL> select name,score,rank() over(partition by name order by score) tt from t;
 
NAME       SCORE         TT
---------- ----- ----------
数学          67          1
数学          77          2
数学          78          3
数学          88          4
数学          99          5
语文          60          1
语文          70          2
语文          80          3   <----
语文          80          3   <----
语文          90          5
 
10 rows selected
 
SQL> select name,score,dense_rank() over(partition by name order by score) tt from t;
 
NAME       SCORE         TT
---------- ----- ----------
数学          67          1
数学          77          2
数学          78          3
数学          88          4
数学          99          5
语文          60          1
语文          70          2
语文          80          3   <----
语文          80          3   <----
语文          90          4
 
10 rows selected
 
SQL> select name,score,row_number() over(partition by name order by score) tt from t;
 
NAME       SCORE         TT
---------- ----- ----------
数学          67          1
数学          77          2
数学          78          3
数学          88          4
数学          99          5
语文          60          1
语文          70          2
语文          80          3  <----
语文          80          4  <----
语文          90          5
 
10 rows selected
 
SQL> select name,score,rank() over(order by score) tt from t;
 
NAME       SCORE         TT
---------- ----- ----------
语文          60          1
数学          67          2
语文          70          3
数学          77          4
数学          78          5
语文          80          6
语文          80          6
数学          88          8
语文          90          9
数学          99         10
 
10 rows selected
 

大家应该明白了吧!呵呵!接下来看应用

一:dense_rank------------------查询每门功课前三名


  select name,score from (select name,score,dense_rank() over(partition by name order by score desc) tt from t) x where x.tt<=3
 
 
NAME       SCORE
---------- -----
数学          99
数学          88
数学          78
语文          90
语文          80
语文          80
 
6 rows selected

二:rank------------------语文成绩70分的同学是排名第几。
   select name,score,x.tt from (select name,score,rank() over(partition by name order by score desc) tt from t) x where x.name='语文' and x.score=70
 
 
NAME       SCORE         TT
---------- ----- ----------
语文          70          4
   
三:row_number——————分页查询
     select xx.* from (select t.*,row_number() over(order by score desc) rowno from t) xx where xx.rowno between 1 and 3;
 
NAME       SCORE      ROWNO
---------- ----- ----------
数学          99          1
语文          90          2
数学          88          3

### Hive 中 RANKDENSE_RANK ROW_NUMBER 的用法及区别 Hive 提供了三种常用的窗口函数:`RANK()`、`DENSE_RANK()` `ROW_NUMBER()`,用于对数据进行排序并分配序号。这三者的主要功能是对数据按照指定条件进行排名或编号,但在具体行为上有显著差异。 --- #### 1. 基本概念与语法结构 这三种函数均属于窗口函数范畴,需配合 `OVER` 子句使用。通用语法如下: ```sql function_name() OVER ([PARTITION BY partition_expression] ORDER BY sort_expression) ``` - **PARTITION BY**: 将数据划分为多个逻辑分区,在每个分区内独立计算排名或编号。 - **ORDER BY**: 定义排序规则,决定每行数据的排列次序。 --- #### 2. 各函数的功能描述 ##### 2.1 `ROW_NUMBER()` `ROW_NUMBER()` 是一种无重复编号的方式,即使遇到相同的值也会依次递增编号。 **特点**: - 对每一行赋予唯一的连续整数值。 - 即使有相同的关键字段值,也不会跳过任何编号。 **示例**: 假设有一张学生分数表 `student_scores`,包含字段 `name`, `score`,以下是按成绩降序为每位学生分配唯一编号的例子: ```sql SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS rn FROM student_scores; ``` 结果可能如下所示[^1]: | name | score | rn | |------|-------|----| | A | 98 | 1 | | B | 95 | 2 | | C | 95 | 3 | 注意:尽管学生 B C 成绩相同,但 `ROW_NUMBER()` 给予他们不同的编号。 --- ##### 2.2 `RANK()` `RANK()` 会对具有相同值的行赋予相同的排名,并且后续排名会跳跃以保持总数一致。 **特点**: - 如果两行或多行拥有相同的值,则它们会被赋予相同的排名。 - 下一排名将从当前最高排名的基础上继续计数,因此会出现断层现象。 **示例**: 同样以上述表格为例,使用 `RANK()` 函数时的结果如下: ```sql SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rk FROM student_scores; ``` 结果可能是这样的[^2]: | name | score | rk | |------|-------|-----| | A | 98 | 1 | | B | 95 | 2 | | C | 95 | 2 | | D | 90 | 4 | 可以看到,由于 B C 并列第二名,下一名(D)直接跳到了第四位。 --- ##### 2.3 `DENSE_RANK()` `DENSE_RANK()` 功能类似于 `RANK()`,但它不会造成排名间断的情况。 **特点**: - 当前行与其他行相同时,给予相同排名。 - 下一排名紧接上一位之后,不会有遗漏。 **示例**: 再次考虑之前的例子,采用 `DENSE_RANK()` 得到的结果将是这样: ```sql SELECT name, score, DENSE_RANK() OVER (ORDER BY score DESC) AS drk FROM student_scores; ``` 输出结果如下[^3]: | name | score | drk | |------|-------|------| | A | 98 | 1 | | B | 95 | 2 | | C | 95 | 2 | | D | 90 | 3 | 在这里,虽然 B C 并列第 2 名,但紧接着的是第 3 名而非第 4 名。 --- #### 3. 使用场景比较 | 特性 | `ROW_NUMBER()` | `RANK()` | `DENSE_RANK()` | |---------------------|-------------------------|------------------------|------------------------| | 是否支持重复排名 | 否 | 是 | 是 | | 排名是否有间隙 | 否 | 是 | 否 | | 数据分布均匀度优先级 | 高 | 较低 | 较高 | | 应用场景 | 取 Top N 或唯一标识 | 处理带平局的比赛排名 | 更紧凑的排名显示 | --- #### 4. 实际案例分析 假设有以下数据集 `scores` 表示学生的科目成绩: | name | subject | score | |------|----------|-------| | Tom | Math | 90 | | Jerry| Math | 90 | | Alice| Math | 85 | | Bob | English | 88 | | Carol| English | 88 | | Dave | English | 86 | 目标是分别查看各科目的前三名情况。 ```sql WITH ranked_data AS ( SELECT name, subject, score, RANK() OVER (PARTITION BY subject ORDER BY score DESC) AS rnk, DENSE_RANK() OVER (PARTITION BY subject ORDER BY score DESC) AS drnk, ROW_NUMBER() OVER (PARTITION BY subject ORDER BY score DESC) AS rn FROM scores ) SELECT * FROM ranked_data WHERE rnk <= 3 OR drnk <= 3 OR rn <= 3; ``` 最终得到的结果可以清晰展示不同函数的行为差异[^4]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值