CUME_DIST()是窗口函数,返回当前行在分区中“≤其值的行数占比”,范围(0,1],相同值行结果相同;在员工绩效分析中可直接反映“绩效≤当前员工的人占全体比例”,比单纯排序更具业务意义。

什么是 CUME_DIST(),它和员工绩效分析有什么关系
CUME_DIST() 是窗口函数,返回当前行在分区内的累积分布比例——即“有多少比例的行值小于等于当前行”。对员工绩效数据来说,它能直接回答:“绩效得分 ≤ 当前员工的人占全体多少?”这比单纯排序更有业务意义。
注意:它的结果范围是 (0, 1],最小值不为 0(因为至少包含自己),且相同绩效值会得到相同结果(不是排名,是占比)。
常见误用现象:CUME_DIST() 写成聚合函数(如 SELECT CUME_DIST() FROM ...),或漏写 OVER() 子句,导致报错 ERROR: window function calls require an OVER clause。
怎么写基础语法才能正确计算绩效占比
关键在于明确三件事:按什么排序、是否分区、是否需要去重处理。
实操建议:
- 必须搭配
ORDER BY在OVER()中,例如OVER (ORDER BY performance_score DESC)—— 绩效越高,占比越靠前(比如 0.95 表示 95% 的人绩效 ≤ 他) - 如果要分部门看各自分布,加
PARTITION BY department,否则默认全表计算 - 不要在
ORDER BY里混用多个字段(如ORDER BY score, name),除非你真想用姓名做二级破 ties —— 这会让相同分数的人被拆开,破坏“同分同占比”语义
简单示例:
SELECT name, department, performance_score, ROUND(CUME_DIST() OVER (ORDER BY performance_score DESC), 3) AS cum_pct FROM employees;
为什么有时结果全是 1.0 或出现非预期小数
这通常不是函数出错,而是数据或逻辑理解偏差。
典型原因:
- 所有
performance_score值相同 → 每行都满足“≤ 当前行”,所以CUME_DIST()全为 1.0 - 用了
ASC排序但期望“高绩效占比高” → 实际上低分排前面,占比数值小(如 0.05),容易误判;应统一用DESC对齐业务直觉 - NULL 值参与排序:默认 NULLS LAST(PostgreSQL/Oracle)或 NULLS FIRST(某些旧版本),会导致占比计算偏移;显式写
ORDER BY performance_score DESC NULLS LAST更可控
和 PERCENT_RANK()、RANK() 混用时要注意什么
三者常被一起查,但语义差异大,混用易误导决策。
核心区别:
-
CUME_DIST():≤ 当前行的比例(含自身,分母是总行数) -
PERCENT_RANK():(rank - 1) / (总行数 - 1),首尾固定为 0 和 1,中间线性插值 -
RANK():纯名次,相同值并列,跳号(如 1,1,3)
举例:5 人绩效为 [80,85,85,90,95]
-
CUME_DIST()结果是 [0.2, 0.6, 0.6, 0.8, 1.0](85 分占前 60%) -
PERCENT_RANK()是 [0.0, 0.5, 0.5, 0.75, 1.0] - 别用
RANK()直接除以总人数算“占比”,那不是分布意义,只是名次归一化
实际分析中,CUME_DIST() 最贴近“绩效分布位置”的原始定义,但需警惕它对极端值敏感——比如一人满分 100,其余都在 60–70 区间,他的占比仍是 1.0,不代表整体水平高。真正要用好,得结合直方图或分位数交叉验证。

















