导读:本期聚焦于小伙伴创作的《如何在SQL中计算分组内的中位数_利用PERCENTILE_CONT窗口函数》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在SQL中计算分组内的中位数_利用PERCENTILE_CONT窗口函数》有用,将其分享出去将是对创作者最好的鼓励。

在SQL数据分析工作中,经常需要按指定维度分组后计算组内数据的中位数,中位数是排序后位于中间位置的数据值,比平均值更能体现数据的典型水平,避免极端值干扰。PERCENTILE_CONT是SQL标准中定义的窗口函数,专门用于计算连续分布的百分位数,当传入参数0.5时,就可以直接得到分组内的中位数,无需手动排序后取中间值。

如何在SQL中计算分组内的中位数_利用PERCENTILE_CONT窗口函数

PERCENTILE_CONT函数基础语法

PERCENTILE_CONT函数的标准语法结构如下:

PERCENTILE_CONT(百分位数值) WITHIN GROUP (ORDER BY 排序字段) OVER (PARTITION BY 分组字段)

其中各个参数的含义为:

  • 百分位数值:取值范围是0到1之间的小数,0.5代表中位数,0代表最小值,1代表最大值
  • WITHIN GROUP (ORDER BY 排序字段):指定计算百分位数时的排序规则,必须指定排序字段
  • OVER (PARTITION BY 分组字段):指定分组的维度,如果不写PARTITION BY则对全表数据计算

单分组场景下的中位数计算

假设我们有一张员工工资表employee_salary,包含员工ID、部门ID、工资三个字段,现在需要计算全公司员工工资的中位数,不需要分组,实现代码如下:

-- 创建测试表
CREATE TABLE employee_salary (
    emp_id INT,
    dept_id INT,
    salary DECIMAL(10,2)
);

-- 插入测试数据
INSERT INTO employee_salary VALUES
(1, 1, 8000),
(2, 1, 9500),
(3, 1, 12000),
(4, 2, 7000),
(5, 2, 8500),
(6, 2, 10000),
(7, 3, 9000),
(8, 3, 11000);

-- 计算全公司工资中位数
SELECT 
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) OVER () AS total_median_salary
FROM employee_salary
LIMIT 1;

上述查询中,OVER()后面没有PARTITION BY子句,所以是对全表所有工资数据排序后计算0.5分位数,也就是中位数。由于窗口函数会对每一行都返回结果,所以使用LIMIT 1只取一条结果即可。

多分组场景下的分组内中位数计算

如果需要按部门分组,计算每个部门内部的工资中位数,只需要在OVER子句中添加PARTITION BY dept_id即可,代码如下:

-- 计算每个部门的工资中位数
SELECT 
    dept_id,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) OVER (PARTITION BY dept_id) AS dept_median_salary
FROM employee_salary
GROUP BY dept_id, salary;

如果希望每个部门只返回一条中位数结果,可以结合子查询去重:

SELECT DISTINCT 
    dept_id,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) OVER (PARTITION BY dept_id) AS dept_median_salary
FROM employee_salary;

查询结果会分别返回部门1、部门2、部门3各自的工资中位数,部门1的三条工资排序后是8000、9500、12000,中位数是9500;部门2的三条工资排序后是7000、8500、10000,中位数是8500;部门3的两条工资排序后是9000、11000,中位数是(9000+11000)/2=10000。

不同数据库的使用差异说明

PERCENTILE_CONT是SQL标准函数,大部分主流数据库都支持,但部分细节有差异:

  • MySQL 8.0及以上版本支持该函数,语法与标准一致
  • PostgreSQL从9.4版本开始支持,语法无差异
  • Oracle支持该函数,同时还可以使用PERCENTILE_DISC函数,后者返回离散分布的百分位数,当数据个数为偶数时,PERCENTILE_CONT会取中间两个值的平均值,PERCENTILE_DISC会取排序后靠前的那个值
  • SQL Server 2012及以上版本支持,语法一致

与传统实现方式的对比

在PERCENTILE_CONT函数出现之前,计算分组内中位数通常需要先排序,再根据数据总数的奇偶性取中间值,实现复杂度高,比如传统方式计算部门工资中位数的代码如下:

WITH salary_rank AS (
    SELECT 
        dept_id,
        salary,
        ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary) AS rn,
        COUNT(*) OVER (PARTITION BY dept_id) AS total_cnt
    FROM employee_salary
)
SELECT 
    dept_id,
    AVG(salary) AS dept_median_salary
FROM salary_rank
WHERE rn IN (FLOOR((total_cnt + 1)/2), CEIL((total_cnt + 1)/2))
GROUP BY dept_id;

对比可见,使用PERCENTILE_CONT函数只需要一行核心代码就可以实现,逻辑更清晰,执行效率也更高,不需要多次扫描表和复杂的排序判断。

注意事项

  • PERCENTILE_CONT计算的是连续百分位数,当数据个数为偶数时,会返回中间两个值的平均值,符合中位数的通用计算规则
  • 排序字段如果有重复值,函数会自动处理重复情况,不需要额外去重
  • 如果分组内只有一条数据,中位数就是该数据本身
  • 百分位数值必须是0到1之间的小数,超出范围会报错

SQL中位数PERCENTILE_CONT窗口函数分组计算修改时间:2026-07-02 06:12:12

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