PERCENTILE_DISC计算中位数包含NULL结果错误 如何实现排除NULL?
问题原因
- 函数逻辑与预期不匹配
PERCENTILE_DISC属于离散百分位数计算函数,仅会返回输入数据集中已存在的数值,不会对中间结果做插值计算。你预期的365是偶数个样本时中间两个值的平均值,属于连续百分位数的计算逻辑,对应PERCENTILE_CONT函数的输出。 - NULL值并未被计入计算
PERCENTILE_DISC本身确实会自动忽略ORDER BY子句指定列的NULL值。你提供的示例中有效非NULL值共4个,排序后为300、310、420、425,PERCENTILE_DISC(0.5)的计算逻辑是取累积分布≥0.5的第一个匹配值,也就是310,和实际运行结果一致,不存在NULL被计入计算的问题。
解决方法
根据你的实际需求选择对应方案即可:
- 如果你需要的是离散中位数(仅返回数据集内已有的值),不需要额外处理NULL,
PERCENTILE_DISC已经自动完成NULL忽略操作。如果需要排除其他无效值(比如0),可以在子查询中添加WHERE条件提前过滤即可,示例如下:
SELECT DISTINCT PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY Numbers) OVER (PARTITION BY Category) from ( select 1 as Category,420 as Numbers union all select 1,425 union all select 1,NULL union all select 1,310 union all select 1,300 ) t1 WHERE Numbers IS NOT NULL AND Numbers != 0 -- 按需求添加过滤规则
- 如果你需要的是常规中位数(偶数个样本时取中间两数的平均值),直接将
PERCENTILE_DISC替换为PERCENTILE_CONT即可,该函数会自动做插值计算,同样支持自动忽略NULL值,示例如下:
SELECT DISTINCT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY Numbers) OVER (PARTITION BY Category) from ( select 1 as Category,420 as Numbers union all select 1,425 union all select 1,NULL union all select 1,310 union all select 1,300 ) t1
上述代码运行后返回的结果就是你预期的365。
内容的提问来源于stack exchange,提问作者Philip
相关产品推荐
相关产品推荐

