详解MySQL中的PERCENT_RANK函数

2024-06-12 04:44

本文主要是介绍详解MySQL中的PERCENT_RANK函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

    • 1. 引入
    • 1. 基本使用
    • 2:分组使用
    • 3:处理重复值
    • 4. 使用优势
      • 4.1 手动计算百分等级
      • 4.2 使用 `PERCENT_RANK` 的优势
      • 4.3 使用 `PERCENT_RANK`
    • 5. 总结

在 MySQL 中,PERCENT_RANK 函数用于计算一个值在其分组中的百分等级。
image.png

它的返回值范围是从 0 到 1,表示一个值在排序后的数据集中相对于其他值的位置。百分等级的计算公式为:
P E R C E N T _ R A N K = rank − 1 total_rows − 1 {PERCENT\_RANK} = \frac{\text{rank} - 1}{\text{total\_rows} - 1} PERCENT_RANK=total_rows1rank1

其中,rank 是当前行的排序位置,total_rows 是总行数。

1. 引入

下面通过一个具体例子来说明 PERCENT_RANK 的用法。

假设我们有一个包含学生分数的表 students_scores,表结构如下:

CREATE TABLE students_scores (student_id INT,student_name VARCHAR(50),score DECIMAL(5, 2)
);

我们向表中插入一些数据:

INSERT INTO students_scores (student_id, student_name, score) VALUES
(1, 'Alice', 85.0),
(2, 'Bob', 90.5),
(3, 'Charlie', 78.0),
(4, 'David', 92.0),
(5, 'Eve', 88.0);

现在,我们希望计算每个学生分数的百分等级。可以使用以下 SQL 查询:

SELECTstudent_id,student_name,score,PERCENT_RANK() OVER (ORDER BY score DESC) AS percent_rank
FROMstudents_scores;

执行上述查询后,将得到以下结果:

student_idstudent_namescorepercent_rank
4David92.00.0000
2Bob90.50.2500
5Eve88.00.5000
1Alice85.00.7500
3Charlie78.01.0000

在这个结果集中,percent_rank 列表示每个学生的分数在所有学生中的相对位置。例如,David 的分数是最高的,因此他的 percent_rank 是 0。Charlie 的分数是最低的,因此他的 percent_rank 是 1。其他学生的 percent_rank 介于 0 和 1 之间,反映了他们的分数在整个分数分布中的相对位置。
image.png

通过这个例子,我们可以看到 PERCENT_RANK 函数如何计算并返回数据集中的每个值的百分等级。

1. 基本使用

假设我们有一个表 employees,包含员工的销售数据:

CREATE TABLE employees (employee_id INT,employee_name VARCHAR(50),sales DECIMAL(10, 2)
);INSERT INTO employees (employee_id, employee_name, sales) VALUES
(1, 'John', 1500.00),
(2, 'Jane', 2000.00),
(3, 'Alice', 2500.00),
(4, 'Bob', 3000.00),
(5, 'Eve', 1000.00);

我们希望计算每个员工销售额的百分等级。可以使用以下查询:

SELECTemployee_id,employee_name,sales,PERCENT_RANK() OVER (ORDER BY sales DESC) AS percent_rank
FROMemployees;

查询结果如下:

employee_idemployee_namesalespercent_rank
4Bob3000.000.0000
3Alice2500.000.2500
2Jane2000.000.5000
1John1500.000.7500
5Eve1000.001.0000

2:分组使用

假设我们有一个包含员工销售数据的表 department_sales,每个员工属于不同的部门:

CREATE TABLE department_sales (employee_id INT,employee_name VARCHAR(50),department VARCHAR(50),sales DECIMAL(10, 2)
);INSERT INTO department_sales (employee_id, employee_name, department, sales) VALUES
(1, 'John', 'Electronics', 1500.00),
(2, 'Jane', 'Electronics', 2000.00),
(3, 'Alice', 'Furniture', 2500.00),
(4, 'Bob', 'Furniture', 3000.00),
(5, 'Eve', 'Electronics', 1000.00),
(6, 'Charlie', 'Furniture', 2800.00);

image.png

我们希望计算每个部门中员工销售额的百分等级。可以使用以下查询:

SELECTemployee_id,employee_name,department,sales,PERCENT_RANK() OVER (PARTITION BY department ORDER BY sales DESC) AS percent_rank
FROMdepartment_sales;

查询结果如下:

employee_idemployee_namedepartmentsalespercent_rank
2JaneElectronics2000.000.0000
1JohnElectronics1500.000.5000
5EveElectronics1000.001.0000
4BobFurniture3000.000.0000
6CharlieFurniture2800.000.5000
3AliceFurniture2500.001.0000

3:处理重复值

假设我们有一个包含学生成绩的表 student_grades,其中有些成绩是重复的:

CREATE TABLE student_grades (student_id INT,student_name VARCHAR(50),grade DECIMAL(5, 2)
);INSERT INTO student_grades (student_id, student_name, grade) VALUES
(1, 'Tom', 85.00),
(2, 'Jerry', 90.00),
(3, 'Anna', 85.00),
(4, 'Mike', 95.00),
(5, 'Sue', 90.00);

我们希望计算每个学生成绩的百分等级。可以使用以下查询:

SELECTstudent_id,student_name,grade,PERCENT_RANK() OVER (ORDER BY grade DESC) AS percent_rank
FROMstudent_grades;

查询结果如下:

student_idstudent_namegradepercent_rank
4Mike95.000.0000
2Jerry90.000.2500
5Sue90.000.2500
1Tom85.000.7500
3Anna85.000.7500

通过以上例子可以看到,PERCENT_RANK 函数在处理不同数据集和需求时都非常灵活和有用。它可以帮助我们更好地理解和分析数据中的分布和排名情况。

4. 使用优势

如果不使用 PERCENT_RANK 函数,我们可以通过子查询和一些数学计算来手动计算百分等级。这种方法相对繁琐,需要多次嵌套查询和排序。下面是一个手动计算百分等级的例子,使用与之前例子相同的 students_scores 表。

4.1 手动计算百分等级

假设我们有以下表数据:

CREATE TABLE students_scores (student_id INT,student_name VARCHAR(50),score DECIMAL(5, 2)
);INSERT INTO students_scores (student_id, student_name, score) VALUES
(1, 'Alice', 85.0),
(2, 'Bob', 90.5),
(3, 'Charlie', 78.0),
(4, 'David', 92.0),
(5, 'Eve', 88.0);

手动计算每个学生分数的百分等级可以通过以下查询实现:

SELECTstudent_id,student_name,score,(SELECT COUNT(*) FROM students_scores AS sub WHERE sub.score < main.score) / (SELECT COUNT(*) - 1 FROM students_scores) AS percent_rank
FROMstudents_scores AS main
ORDER BYscore DESC;

上述查询的结果与使用 PERCENT_RANK 函数的结果是相同的。

4.2 使用 PERCENT_RANK 的优势

  1. 简洁性和易读性:使用 PERCENT_RANK 函数可以简化查询的编写,使得代码更为简洁和易读。手动计算百分等级需要嵌套查询和计算,增加了复杂性。

  2. 性能优化:数据库引擎通常会对窗口函数进行优化,使其执行效率更高。手动计算可能无法充分利用这些优化,从而导致查询性能较低。

  3. 维护性:使用内置函数减少了自定义计算逻辑,当需求发生变化时,代码的维护和修改也更加方便。

  4. 减少错误:手动计算时容易出错,例如在计算总行数、排序以及分组等过程中,使用 PERCENT_RANK 函数可以减少这些人为错误。

4.3 使用 PERCENT_RANK

我们再来回顾一下如何使用 PERCENT_RANK 函数:

SELECTstudent_id,student_name,score,PERCENT_RANK() OVER (ORDER BY score DESC) AS percent_rank
FROMstudents_scores;

这个查询简单明了,直接利用 PERCENT_RANK 函数计算百分等级,避免了复杂的嵌套查询和计算逻辑。

5. 总结

使用 PERCENT_RANK 函数在简化查询编写、提高性能和减少错误方面具有明显的优势。因此,在可以使用窗口函数的场景下,推荐优先使用 PERCENT_RANK 而不是手动计算百分等级。

这篇关于详解MySQL中的PERCENT_RANK函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1053224

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有