详解MySQL中的PERCENT_RANK函数
目录
- 1. 引入
- 1. 基本使用
- 2:分组使用
- 3:处理重复值
- 4. 使用优势
- 4.1 手动计算百分等级
- 4.2 使用 `PERCENT_RANK` 的优势
- 4.3 使用 `PERCENT_RANK`
- 5. 总结
在 MySQL 中,PERCENT_RANK 函数用于计算一个值在其分组中的百分等级。

它的返回值范围是从 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_rows−1rank−1
其中,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_id | student_name | score | percent_rank |
|---|---|---|---|
| 4 | David | 92.0 | 0.0000 |
| 2 | Bob | 90.5 | 0.2500 |
| 5 | Eve | 88.0 | 0.5000 |
| 1 | Alice | 85.0 | 0.7500 |
| 3 | Charlie | 78.0 | 1.0000 |
在这个结果集中,percent_rank 列表示每个学生的分数在所有学生中的相对位置。例如,David 的分数是最高的,因此他的 percent_rank 是 0。Charlie 的分数是最低的,因此他的 percent_rank 是 1。其他学生的 percent_rank 介于 0 和 1 之间,反映了他们的分数在整个分数分布中的相对位置。

通过这个例子,我们可以看到 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_id | employee_name | sales | percent_rank |
|---|---|---|---|
| 4 | Bob | 3000.00 | 0.0000 |
| 3 | Alice | 2500.00 | 0.2500 |
| 2 | Jane | 2000.00 | 0.5000 |
| 1 | John | 1500.00 | 0.7500 |
| 5 | Eve | 1000.00 | 1.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);

我们希望计算每个部门中员工销售额的百分等级。可以使用以下查询:
SELECTemployee_id,employee_name,department,sales,PERCENT_RANK() OVER (PARTITION BY department ORDER BY sales DESC) AS percent_rank
FROMdepartment_sales;
查询结果如下:
| employee_id | employee_name | department | sales | percent_rank |
|---|---|---|---|---|
| 2 | Jane | Electronics | 2000.00 | 0.0000 |
| 1 | John | Electronics | 1500.00 | 0.5000 |
| 5 | Eve | Electronics | 1000.00 | 1.0000 |
| 4 | Bob | Furniture | 3000.00 | 0.0000 |
| 6 | Charlie | Furniture | 2800.00 | 0.5000 |
| 3 | Alice | Furniture | 2500.00 | 1.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_id | student_name | grade | percent_rank |
|---|---|---|---|
| 4 | Mike | 95.00 | 0.0000 |
| 2 | Jerry | 90.00 | 0.2500 |
| 5 | Sue | 90.00 | 0.2500 |
| 1 | Tom | 85.00 | 0.7500 |
| 3 | Anna | 85.00 | 0.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 的优势
-
简洁性和易读性:使用
PERCENT_RANK函数可以简化查询的编写,使得代码更为简洁和易读。手动计算百分等级需要嵌套查询和计算,增加了复杂性。 -
性能优化:数据库引擎通常会对窗口函数进行优化,使其执行效率更高。手动计算可能无法充分利用这些优化,从而导致查询性能较低。
-
维护性:使用内置函数减少了自定义计算逻辑,当需求发生变化时,代码的维护和修改也更加方便。
-
减少错误:手动计算时容易出错,例如在计算总行数、排序以及分组等过程中,使用
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函数
目录 1. 引入1. 基本使用2:分组使用3:处理重复值4. 使用优势4.1 手动计算百分等级4.2 使用 PERCENT_RANK 的优势4.3 使用 PERCENT_RANK 5. 总结 在 MySQL 中,PERCENT_RANK 函数用于计算一个值在其分组中的百分等级。 它的返回值范围是从 0 …...
宏任务与微任务
一、宏任务 1、概念 指消息队列中等地被主线程执行的事件 2、种类 script主代码块、setTimeout 、setInterval 、nodejs的setImmediate 、MessageChannel(react的fiber用到)、postMessage、网络I/O、文件I/O、用户交互的回调等事件、UI渲染事件&#x…...
昇思大模型学习·第一天
mindspore快速入门回顾 导入mindspore包 处理数据集 下载mnist数据集进行数据集预处理 MnistDataset()方法train_dataset.get_col_names() 打印列名信息使用create_tuple_iterator 或create_dict_iterator对数据集进行迭代访问 网络构建 mindspore.nn: 构建所有网络的基类用…...
python调用chatgpt
简单写了一下关于文本生成接口的调用,其余更多的调用方法可在官网查看 import os from dotenv import load_dotenv, find_dotenv from openai import OpenAI import httpxdef gpt_config():# 为了安全起见,将key写到当前项目根目录下的.env文件中# find…...
YOLOV8 目标检测:训练自定义数据集
1、下载 yolov8项目:ultralytics/ultralytics:新增 - PyTorch 中的 YOLOv8 🚀 > ONNX > OpenVINO > CoreML > TFLite --- ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreM…...
动态更新自建的Redis连接池连接数量
/*** 定时更新Redis连接池信息,防止资源让费*/private static final ScheduledThreadPoolExecutor DYNAMICALLY_UPDATE_REDIS_POOL_THREAD new ScheduledThreadPoolExecutor(1, new ThreadFactory() {Overridepublic Thread newThread(Runnable r) {Thread thread …...
浅谈设计师的设计地位
在当今这个创意无限的时代,设计师的地位日益凸显。他们以独特的视角和精湛的技能,为我们的生活带来了无尽的色彩与灵感。然而,随着行业的不断发展,设计师如何在众多同行中脱颖而出,提升自己的设计地位呢?答…...
C/C++ string模拟实现
1.模拟准备 1.1因为是模拟string,防止与库发生冲突,所以需要命名空间namespace隔离一下,我们来看一下基本内容 namespace yx {class string{private://char _buff[16]; lunix下小于16字节就存buff里char* _str;size_t _size;size_t _capac…...
微信小程序学习(八):behaviors代码复用
小程序的 behaviors 方法是一种代码复用的方式,可以将一些通用的逻辑和方法提取出来,然后在多个组件中复用,从而减少代码冗余,提高代码的可维护性。 如果需要 behavior 复用代码,需要使用 Behavior() 方法,…...
【The design pattern of Attribute-Based Dynamic Routing Pattern (ADRP)】
In ASP.NET Core, routing is one of the core functionalities that maps HTTP requests to the corresponding controller actions. While “Route-Driven Design Pattern” is a coined name for a design pattern, we can construct a routing-centric design pattern base…...
2713. 矩阵中严格递增的单元格数
题目 给定一个 m x n 的整数矩阵 mat,我们需要找出从某个单元格出发可以访问的最大单元格数量。移动规则是可以从当前单元格移动到同一行或同一列的任何其他单元格,但目标单元格的值必须严格大于当前单元格的值。需要返回最大可访问的单元格数量。 示例…...
git创建子模块
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。 Git …...
把Deepin塞进U盘,即插即用!Deepin To Go来袭
前言 小伙伴之前在某篇文章下留言说:把Deepin塞进U盘的教程。 这不就来了吗? 事实是可以的。这时候你要先做点小准备: 一个大小为8GB或以上的普通U盘 一个至少64GB或以上的高速U盘 一个Deepin系统镜像文件 普通U盘的大概介绍࿱…...
给【AI硬件】创业者的论文、开源项目和产品整理
一、AI 硬件精选论文 《DrEureka: Language Model Guided Sim-To-Real Transfer》 瑜伽球上遛「狗」这项研究由宾夕法尼亚大学、 NVIDIA 、得克萨斯大学奥斯汀分校的研究者联合打造,并且完全开源。他们提出了 DrEureka(域随机化 Eureka)&am…...
模拟面试题卷二
1. 什么是JavaEE框架,你能列举一些常用的JavaEE框架吗? 答:JavaEE框架是一套用于开发企业级应用的技术规范和工具集合。常用的JavaEE框架有Spring、Hibernate、Struts、JSF等。 2. 请解释一下面向对象技术和设计原则是什么,你能…...
22种常用设计模式示例代码
文章目录 创建型模式结构型模式行为模式 仓库地址https://github.com/Xiamu-ssr/DesignPatternsPractice 参考教程 refactoringguru设计模式-目录 创建型模式 软件包复杂度流行度工厂方法factorymethod❄️⭐️⭐️⭐️抽象工厂abstractfactory❄️❄️⭐️⭐️⭐️生成器bui…...
Java面试题:对比ArrayList和LinkedList的内部实现,以及它们在不同场景下的适用性
ArrayList和LinkedList是Java中常用的两个List实现,它们在内部实现和适用场景上有很大差异。下面是详细的对比分析: 内部实现 ArrayList 数据结构:内部使用动态数组(即一个可变长的数组)实现。存储方式:…...
ping: www.baidu.com: 未知的名称或服务(IP号不匹配)
我用的是VMware上的Red Hat Enterprise Linux 9,出现了能联网但ping不通外网的情况。 问题描述:设置中显示正常连接,而且虚拟机右上角有联网的图标,但不能通外网。 按照网上教程修改了/etc/resolv.conf和/etc/sysconfig/network-…...
谷神前端组件增强:子列表
谷神Ag-Grid导出Excel // 谷神Ag-Grid导出Excel let allDiscolumns detailTable.getAllDisColumns() let columnColIds columns.map(column > column.colId) let columnKeys columnColIds.filter(item > ![select, "_OPT_FIELD_"].includes(item)) detailT…...
测试cudaStream队列的深度
测试cudaStream队列的深度 一.代码二.编译运行[得出队列深度为512] 以下代码片段用于测试cudaStream队列的深度 方法: 主线程一直发任务,启一个线程cudaEventQuery查询已完成的任务,二个计数器的值相减 一.代码 #include <iostream> #include <thread> #include …...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
