导读:本期聚焦于小伙伴创作的《如何在排名分析中应用PERCENT_RANK()和CUME_DIST()?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在排名分析中应用PERCENT_RANK()和CUME_DIST()?》有用,将其分享出去将是对创作者最好的鼓励。

在进行数据排名分析时,我们经常需要了解某一行数据在整个数据集中的相对位置,而不仅仅是它在排序列表中的绝对次序。PERCENT_RANK() 和 CUME_DIST() 作为 SQL 窗口函数中的两个重要成员,分别从百分比排名和累积分布的角度提供了这种相对位置信息。它们虽然是 SQL 标准函数,但很多开发者对它们的具体差异和应用场景仍存在困惑。下面我们就来详细解析这两个函数的概念、语法,并通过实际例子展示它们在排名分析中的威力。

函数基础概念与语法

这两个函数都属于窗口函数,需要结合 OVER() 子句使用,并且通常需要配合 ORDER BY 来指定排序依据。

PERCENT_RANK()

此函数返回某一行在分区内的相对排名,计算公式为:(rank - 1) / (total_rows - 1)。其中 rank 是该行的 RANK() 值(相同值并列排名),total_rows 是分区内的总行数。返回结果的范围是 0 到 1 之间,包括 0 和 1。排名第一的行总是 0,最后一行总是 1(如果总行数大于 1)。

PERCENT_RANK() OVER (
    [PARTITION BY partition_expression]
    ORDER BY sort_expression
)

CUME_DIST()

该函数计算某一行在分区内的累积分布,即严格小于等于当前值的行数占总行数的比例。计算公式为:count(rows <= current_value) / total_rows。返回结果范围也是 0 到 1 之间,且最后一行的值一定为 1。注意它与 PERCENT_RANK 的区别:相同值会得到相同的 CUME_DIST,但计算基数不同。

CUME_DIST() OVER (
    [PARTITION BY partition_expression]
    ORDER BY sort_expression
)

核心区别对比

为了直观理解两者的差异,我们用一个简单的 5 行数据(假设没有并列)来对比:

RANK()PERCENT_RANK()CUME_DIST()
1010.000.20
2020.250.40
3030.500.60
4040.750.80
5051.001.00

可以看到,PERCENT_RANK 的第一行永远是 0,最后一行永远是 1;而 CUME_DIST 的第一行则取决于行数(这里是 1/5=0.2),最后一行始终为 1。两者虽然取值范围相同,但语义不同:PERCENT_RANK 强调的是排名的百分比位置(比当前排名低的比例),而 CUME_DIST 强调的是累积概率(小于等于当前值的比例)。

实际应用场景

下面通过两个典型的业务场景来演示这两个函数如何使用。

场景一:学生考试成绩排名分析

假设我们有一个成绩表 exam_scores,包含学生姓名和分数。我们希望了解每个学生的成绩在整个年级中的相对位置,既要知道他的百分比排名,也要知道有多少比例的学生成绩小于等于他。

-- 建表及插入测试数据
CREATE TABLE exam_scores (
    id INTEGER PRIMARY KEY,
    student_name VARCHAR(50),
    score DECIMAL(5,2)
);

INSERT INTO exam_scores VALUES
(1, '张三', 92),
(2, '李四', 85),
(3, '王五', 78),
(4, '赵六', 96),
(5, '陈七', 88),
(6, '周八', 91),
(7, '吴九', 73),
(8, '郑十', 99);

现在查询每个学生的成绩、RANK、PERCENT_RANK 和 CUME_DIST:

SELECT
    student_name,
    score,
    RANK() OVER (ORDER BY score DESC) AS rk,
    PERCENT_RANK() OVER (ORDER BY score DESC) AS pct_rank,
    CUME_DIST() OVER (ORDER BY score DESC) AS cume_dist
FROM exam_scores
ORDER BY score DESC;

查询结果示例(基于上述数据):

student_name | score | rk | pct_rank      | cume_dist
-------------+-------+----+---------------+-----------
郑十         | 99    | 1  | 0.000000      | 0.125000
赵六         | 96    | 2  | 0.142857      | 0.250000
张三         | 92    | 3  | 0.285714      | 0.375000
周八         | 91    | 4  | 0.428571      | 0.500000
陈七         | 88    | 5  | 0.571429      | 0.625000
李四         | 85    | 6  | 0.714286      | 0.750000
王五         | 78    | 7  | 0.857143      | 0.875000
吴九         | 73    | 8  | 1.000000      | 1.000000

解释一下:张三成绩 92 分,排名第 3(并列时会有变化,此处无并列)。PCT_RANK 为 0.285714,表示大约 28.6% 的人排名比他低(不包括他自己);CUME_DIST 为 0.375,表示有 37.5% 的人成绩小于等于 92 分。两个值不同,反映的含义也不同。

场景二:销售业绩分部门排名

如果我们按部门分区,想了解每个销售代表的业绩在其部门内的相对位置。使用 PARTITION BY 子句即可。

CREATE TABLE sales (
    emp_id INT,
    dept_id INT,
    amount DECIMAL(10,2)
);

INSERT INTO sales VALUES
(101, 1, 15000),
(102, 1, 22000),
(103, 1, 18000),
(201, 2, 25000),
(202, 2, 20000),
(203, 2, 23000),
(204, 2, 21000);
SELECT
    dept_id,
    emp_id,
    amount,
    PERCENT_RANK() OVER (PARTITION BY dept_id ORDER BY amount DESC) AS dept_pct_rank,
    CUME_DIST() OVER (PARTITION BY dept_id ORDER BY amount DESC) AS dept_cume_dist
FROM sales
ORDER BY dept_id, amount DESC;

结果为我们揭示了每个部门内部业绩的百分比排名和累积分布情况,便于管理者识别绩优员工和需改进员工。

注意事项与常见误区

  • 并列值的处理:两个函数对并列值的处理都基于 RANK 函数。PERCENT_RANK 会跳过排名间隙,而 CUME_DIST 对并列行赋予相同的累积概率值。例如,如果有两个并列第一名,PERCENT_RANK 会计算为 0,而 CUME_DIST 为 2/总行数。
  • 空值处理:默认情况下,ORDER BY 中的空值会被视为最大值或最小值(依据数据库具体实现)。建议在使用前明确处理空值,或在查询中加入 NULLS LAST 等子句。
  • 性能:窗口函数需要对分区内数据排序,大量数据时可能影响性能。但相比手动计算排名再算比例,SQL 窗口函数更高效也更简洁。
  • 不要混淆两者:在进行分位数划分时,通常使用 NTILE 函数而非 PERCENT_RANK;而 CUME_DIST 更适合用于累积分布图或统计检验。

总结

PERCENT_RANK() 和 CUME_DIST() 是 SQL 排名分析中非常实用的窗口函数。前者告诉你某个值在排序中的百分比排名(基于排名位置),后者告诉你小于等于该值的比例(基于行数累计)。理解它们的计算逻辑和语义差异,能够帮助你在数据探索、报表制作、统计学分析中做出更准确的判断。当你需要量化一个数值在群体中的相对位置时,这两个函数就是你的得力助手。

PERCENT_RANKCUME_DIST排名分析SQL窗口函数分布函数修改时间:2026-06-08 20:18:42

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。