Rank

1,函数说明

RANK() 排序相同时会重复,总数不会变

DENSE_RANK() 排序相同时会重复,总数会减少

ROW_NUMBER() 会根据顺序计算

2,数据准备

name

subject

score

孙悟空

语文

87

孙悟空

数学

95

孙悟空

英语

68

大海

语文

94

大海

数学

56

大海

英语

84

宋宋

语文

64

宋宋

数学

86

宋宋

英语

84

婷婷

语文

65

婷婷

数学

85

婷婷

英语

78

3,需求

      计算每门学科成绩排名

4,创建本地movie.txt,导入数据

      vi score.txt

5,创建hive表并导入数据

create table score(

name string,

subject string,

score int)

row format delimited fields terminated by "\t";

load data local inpath '/opt/module/datas/score.txt' into table score;

6,按需求查询数据

select name,

subject,

score,

rank() over(partition by subject order by score desc) rp,

dense_rank() over(partition by subject order by score desc) drp,

row_number() over(partition by subject order by score desc) rmp

from score;

 

name    subject score   rp      drp     rmp

孙悟空  数学    95      1       1       1

宋宋      数学    86      2       2       2

婷婷      数学    85      3       3       3

大海      数学    56      4       4       4

宋宋      英语    84      1       1       1

大海      英语    84      1       1       2

婷婷      英语    78      3       2       3

孙悟空  英语    68      4       3       4

大海      语文    94      1       1       1

孙悟空  语文    87      2       2       2

婷婷      语文    65      3       3       3

宋宋      语文    64      4       4       4

在SQL中,`RANK()` 和 `DENSE_RANK()` 是常用的窗口函数,用于为结果集的每一行分配一个排名值。它们通常用于需要对数据进行排序并为并列的行分配排名的场景,例如排行榜、销售排名等。两者的主要区别在于如何处理并列值。 ### `RANK()` 窗口函数 `RANK()` 函数会根据排序列的值为每一行分配一个排名。如果有多个行具有相同的排序值,则这些行会获得相同的排名,但下一行的排名会跳过相应的数字。例如,在一个销售排行榜中,如果有两个销售人员并列第一,则下一名销售人员的排名为3。 ```sql SELECT employee_id, sales, RANK() OVER (ORDER BY sales DESC) AS sales_rank FROM sales_data; ``` 在上述查询中,`RANK()` 根据销售额 (`sales`) 降序排列,并为每一行分配排名。如果两个员工的销售额相同,则他们的排名相同,而下一名员工的排名将跳过相应的数字。 ### `DENSE_RANK()` 窗口函数 与 `RANK()` 不同,`DENSE_RANK()` 在处理并列值时不会跳过排名。例如,如果有两个并列第一的销售人员,则下一名销售人员的排名为2。 ```sql SELECT employee_id, sales, DENSE_RANK() OVER (ORDER BY sales DESC) AS dense_sales_rank FROM sales_data; ``` 在上述查询中,`DENSE_RANK()` 同样根据销售额降序排列,但即使有并列的行,排名也不会跳过数字。 ### 使用场景与问题排查 在实际使用 `RANK()` 和 `DENSE_RANK()` 时,可能会遇到以下问题: 1. **错误的排序逻辑**:确保 `ORDER BY` 子句的排序逻辑正确。如果排序列的值不符合预期,排名可能会出现偏差。 2. **性能问题**:在大型数据集上使用窗口函数时,可能会导致性能下降。可以通过在排序列上创建索引来优化性能。 3. **分区使用不当**:窗口函数支持 `PARTITION BY` 子句,可以将数据划分为多个分区,并在每个分区内独立计算排名。如果未正确使用 `PARTITION BY`,可能会导致排名结果不符合预期。 4. **并列值的处理**:根据需求选择 `RANK()` 或 `DENSE_RANK()`。如果需要跳过排名,选择 `RANK()`;如果不需要跳过排名,选择 `DENSE_RANK()`。 ### 示例 以下是一个结合 `RANK()` 和 `DENSE_RANK()` 的示例,展示如何在实际场景中使用这些函数: ```sql SELECT department, employee_id, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS salary_rank, DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_salary_rank FROM employees; ``` 在上述查询中,数据按部门 (`department`) 分区,并在每个分区内根据薪资 (`salary`) 降序排列。`RANK()` 和 `DENSE_RANK()` 分别计算每个员工在部门内的薪资排名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值