相对排名怎么算
PERCENT_RANK() 给出相对排名,公式是(名次减一)除以(总行数减一),取值落在 0 到 1 之间。它回答的是「排在前面百分之多少」,常用于分位定位与分层,与按行数等分的 NTILE 是两回事。
基本信息
| 取值范围 | 0 到 1 |
|---|---|
| 边界 | 分区内数值居首者为 0,居末者为 1 |
| 公式 | (名次 - 1) / (总行数 - 1) |
| 对比 | CUME_DIST 表示小于等于当前值的比例,并列行结果不同 |
| 适用平台 | MySQL 8.0+ 与 PostgreSQL |
典型使用场景
- 判断某个值处在什么百分位
- 按相对排名给用户分层
- 报表里标注「超过了多少比例的用户」
- 与 CUME_DIST 对比理解并列行差异
- 用于分位数的近似定位
示例
示例
-- 相对排名:数值越小说明越靠前
SELECT name, score,
ROUND(PERCENT_RANK() OVER (ORDER BY score DESC), 4) AS pr
FROM exams;
-- 分组内计算:每个班级各自的相对排名
SELECT class_id, name, score,
ROUND(PERCENT_RANK() OVER (PARTITION BY class_id ORDER BY score DESC), 4) AS pr
FROM exams;
-- 与 CUME_DIST 对比:并列行的结果不同
SELECT name, score,
PERCENT_RANK() OVER (ORDER BY score DESC) AS pr,
CUME_DIST() OVER (ORDER BY score DESC) AS cd
FROM exams;与相邻函数对照
| 函数 | 取值 | 并列行表现 |
|---|---|---|
| PERCENT_RANK | 0 到 1 | 并列行取值相同 |
| CUME_DIST | 大于 0 到 1 | 表示小于等于当前值的比例 |
| RANK | 整数名次 | 并列跳号 |
| DENSE_RANK | 整数名次 | 并列不跳号 |
| NTILE | 桶号 | 按行数等频分桶 |
分区只有一行时 PERCENT_RANK 返回 0:公式分母为零,数据库按约定返回 0,统计口径要单独说明。
「按行数等分」用 NTILE,「按数值比例定位」用 PERCENT_RANK,两者不可互换:前者的桶大小由行数决定,后者由名次比例决定。
报表里常把它换算成「超过多少比例的用户」:展示时用 1 减去相对排名更符合直觉,直接给出原值容易让人读反。
分组维度决定含义:按整体算与按分组算得到的相对排名完全不同,报表里要写清是全局排名还是组内排名。
它与分位数搭配使用效果更好:相对排名给出位置,分位数给出取值,两者一起看才能说清分布形态。