详解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 …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
