百分比排名用于衡量某个数值在有序数据集中的相对位置,取值范围为0到1,0表示排名最低,1表示排名最高。SQL提供的PERCENT_RANK窗口函数可以直接完成这类计算,无需手动编写复杂的排名逻辑。

PERCENT_RANK函数基本语法
PERCENT_RANK属于窗口函数的一种,基本语法结构如下:
PERCENT_RANK() OVER (
[PARTITION BY 分组列]
ORDER BY 排序列 [ASC|DESC]
)
其中PARTITION BY是可选参数,用于将数据集按指定列分组,在每个分组内单独计算百分比排名;ORDER BY是必填参数,用于指定排序规则,决定排名的先后顺序。
百分比排名计算逻辑
PERCENT_RANK的计算公式为:(当前行排名 - 1) / (分组内总行数 - 1)。需要注意以下规则:
- 排名从1开始计数,最低排名为1,最高排名为分组内总行数
- 如果分组内只有1行数据,分母为0,此时百分比排名为0
- 相同数值的行会获得相同的排名,后续排名会跳过重复的数量
实操案例演示
案例1:单表全量数据百分比排名
假设有一张学生成绩表student_score,结构如下:
| id | student_name | score |
|---|---|---|
| 1 | 张三 | 85 |
| 2 | 李四 | 92 |
| 3 | 王五 | 78 |
| 4 | 赵六 | 92 |
| 5 | 钱七 | 88 |
现在需要计算每个学生成绩在所有学生中的百分比排名,按成绩降序排列,成绩越高排名越靠前:
SELECT
student_name,
score,
PERCENT_RANK() OVER (ORDER BY score DESC) AS percent_rank
FROM student_score;
执行结果如下:
| student_name | score | percent_rank |
|---|---|---|
| 李四 | 92 | 0 |
| 赵六 | 92 | 0 |
| 钱七 | 88 | 0.5 |
| 张三 | 85 | 0.75 |
| 王五 | 78 | 1 |
计算逻辑说明:总共有5行数据,最高分92分有2人,排名为1,按照公式计算(1-1)/(5-1)=0;钱七成绩88分排名第3,(3-1)/(5-1)=0.5;张三85分排名第4,(4-1)/(5-1)=0.75;王五78分排名第5,(5-1)/(5-1)=1。
案例2:分组内百分比排名
如果学生成绩表新增class字段表示班级,需要计算每个学生在班级内的成绩百分比排名:
SELECT
class,
student_name,
score,
PERCENT_RANK() OVER (PARTITION BY class ORDER BY score DESC) AS class_percent_rank
FROM student_score;
此时会先按class分组,在每个班级内单独计算百分比排名,不同班级的计算互不影响。
使用注意事项
- PERCENT_RANK是标准SQL函数,主流数据库如MySQL 8.0+、PostgreSQL、SQL Server、Oracle都支持,但低版本数据库可能需要手动实现计算逻辑
- 排序规则会影响最终排名结果,需要根据业务需求选择升序还是降序,比如成绩排名通常用降序,耗时排名通常用升序
- 如果不需要分组计算,不要添加
PARTITION BY子句,否则会按分组拆分计算范围
低版本数据库手动实现百分比排名
如果使用的数据库不支持PERCENT_RANK函数,可以通过排名函数和总行数手动计算:
SELECT
student_name,
score,
(rank_val - 1) * 1.0 / (total_count - 1) AS percent_rank
FROM (
SELECT
student_name,
score,
RANK() OVER (ORDER BY score DESC) AS rank_val,
COUNT(*) OVER () AS total_count
FROM student_score
) t;
上述逻辑中先用RANK()计算排名,再用COUNT(*)获取总行数,最后按照百分比排名公式计算出结果,和PERCENT_RANK函数的效果一致。
SQLPERCENT_RANK百分比排名窗口函数修改时间:2026-07-21 05:06:21