在数据分析中,我们经常需要观察某个分组内部的数据分布状态,例如每个销售团队里成员业绩的排名比例,或者每个品类商品价格的相对位置。传统的GROUP BY只能输出逐组的聚合结果,会丢失个体记录。SQL中的窗口函数能够在保持原表行数的基础上,按指定分区和排序规则计算分组内的分布指标,是实现这类需求的关键手段。

什么是窗口函数
窗口函数通过OVER子句定义窗口,也就是数据的计算范围。基本语法如下:
函数名(列) OVER ( PARTITION BY 分组列 ORDER BY 排序列 ) AS 别名
其中PARTITION BY对应分组,类似于GROUP BY但不合并行;ORDER BY决定组内计算顺序。
常用分布分析函数
1. ROW_NUMBER与RANK
这两个函数用来标记组内位置:
ROW_NUMBER:组内从1开始连续编号,不并列RANK:相同值并列,后续序号跳过DENSE_RANK:相同值并列,后续序号连续
2. PERCENT_RANK与CUME_DIST
它们返回组内相对比例:
| 函数 | 含义 |
|---|---|
| percent_rank() | (组内排名-1)/(组内行数-1) |
| cume_dist() | 小于等于当前值的行数占比 |
3. NTILE分桶
NTILE(n)将组内数据均分成n个桶,便于做四分位或十分位分析。
实战示例
假设有员工表emp,包含dept(部门)、name(姓名)、salary(薪资)。我们想分析各部门薪资分布。
SELECT dept, name, salary, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rk, PERCENT_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS pr, NTILE(4) OVER (PARTITION BY dept ORDER BY salary DESC) AS quartile FROM emp;
上述查询为每一行计算了在部门内的降序薪资排名、百分比排名以及四分位桶号,原始数据行不变。
应用建议
做分组内分布分析时,先明确业务关心的分布粒度。若只需头尾部,用ROW_NUMBER加条件过滤即可;若需看相对位置,PERCENT_RANK更直观;若要做均衡分层,NTILE最方便。注意在OVER中正确设置PARTITION BY与ORDER BY,避免因排序缺失导致分布结果无意义。
窗口函数不改变原表行数,因此可与普通列和其他聚合同时查询,非常适合报表中的分组内统计。
SQL窗口函数分组分析数据分布percent_rank修改时间:2026-07-25 02:09:22