PERCENTILE_CONT 和 PERCENTILE_DISC 的核心区别在哪
二者都用于计算分位数,但中位数(50% 分位)结果可能不同:PERCENTILE_CONT 线性插值,返回连续分布下的理论值;PERCENTILE_DISC 直接取排序后存在的实际值(向下取整逻辑),不插值。
比如数据 [1, 3, 5, 7]:
– PERCENTILE_CONT(0.5) 插值得到 4.0(3 和 5 中间)
– PERCENTILE_DISC(0.5) 返回 3(第 2 个值,即 floor((n+1)/2) = 2)
- 当需要严格等于原始数据中的某个值(如报表要求“真实出现过的中位销售额”),用
PERCENTILE_DISC - 当需数学上更平滑的中心趋势(如统计建模输入),用
PERCENTILE_CONT - 空值默认被忽略,但若列含大量
NULL,实际参与计算的行数会减少,结果易偏移
语法写错会导致直接报错或静默错误
常见硬伤:漏掉 WITHIN GROUP、括号位置错、ORDER BY 缺失。PostgreSQL / SQL Server / Oracle 都强制要求该结构,MySQL 不支持这两个函数(8.0+ 仅支持 PERCENT_RANK 等替代方案)。
正确写法长这样:
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY sales_amount) AS median_cont,
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY sales_amount) AS median_disc
FROM orders;
-
PERCENTILE_CONT和PERCENTILE_DISC是聚合函数,不能出现在 WHERE 或 GROUP BY 中,只能在 SELECT 或 HAVING(配合 GROUP BY)里用 -
WITHIN GROUP括号内必须是单列ORDER BY,不支持表达式如ORDER BY ABS(price)(部分数据库报错) - 参数必须是
0到1的常量小数,不能是列名或子查询(如PERCENTILE_CONT(pct_col)会失败)
按组算中位数时容易漏掉 PARTITION BY
想算每个部门的中位薪资?别只加 GROUP BY dept——那会把整个函数当普通聚合用,报错或结果错乱。必须用窗口函数写法,靠 OVER + PARTITION BY。