var()和variance()可直接计算方差,但需区分样本与总体;误用会导致结果系统性偏高5%~20%,小分组时尤为显著。

直接用 VAR() 或 VARIANCE() 就能算,但必须分清你算的是样本还是总体——错用会导致结果系统性偏高约 5%~20%,尤其在小分组(
VAR() 和 VAR_POP() 到底该选哪个
核心就一条:如果这组数据是你全部关心的对象(比如“2026 年 4 月北京各门店销售额”),用 VAR_POP();如果只是从更大集合里抽出来的一份样本(比如“随机抽 50 家店估算全国趋势”),才用 VAR() 或 VARIANCE()。
常见误判点:
-
VAR()在 PostgreSQL 和 Azure Databricks 中等价于VAR_SAMP()(分母是n−1),不是总体版 - MySQL 的
VARIANCE()也是样本方差,但它把VAR_POP()当作总体方差的唯一写法 - SQL Server 根本没有
VAR_POP(),得靠VAR() * (COUNT(*) - 1.0) / COUNT(*)手动校正 - SQLite 不支持任何方差函数,只能写
AVG(x*x) - AVG(x)*AVG(x),但该式子在含 NULL 或空组时会出错
GROUP BY 分组方差最常踩的三个坑
写 SELECT dept, VAR(salary) FROM emp GROUP BY dept 看似简单,实际容易报错或得错数:
- 报错
ERROR: column "name" must appear in the GROUP BY clause→ 检查SELECT列表里有没有漏掉聚合或没进GROUP BY的非聚合列 - 报错
function var(text) does not exist→salary实际是TEXT类型,加salary::numeric强转 - 结果全是
NULL→ 分组内非空值少于 2 个(VAR_SAMP要求至少两个有效数字),换VAR_POP()可得 0.0(仅当有值)
NULL 值和空分组怎么处理
所有主流数据库的方差函数都自动忽略 NULL,但边界情况差异大:
- 整组全
NULL:所有VAR*函数返回NULL - 组内只有一个非
NULL值:VAR_SAMP()返回NULL,VAR_POP()返回0.0 - 空表(0 行):
VAR_POP()和VAR_SAMP()都返回NULL,不是 0 —— 如果业务逻辑依赖“0 表示无波动”,得用COALESCE(VAR_POP(x), 0) - 想排除某些行再算方差?PostgreSQL/MySQL 支持
VAR_POP(x) FILTER (WHERE status = 'active'),SQL Server 得套子查询或CASE WHEN
跨数据库迁移时函数名不兼容怎么办
写 SQL 时别硬记 “VAR 就是方差”,不同库默认行为和函数名根本不统一:
- PostgreSQL:认
VAR_POP()、VAR_SAMP(),不认VARIANCE() - MySQL:有
VARIANCE()和VAR_POP(),但没VAR() - SQL Server:只有
VAR()和VARP()(注意是 VARP,不是 VAR_POP) - Azure Databricks:
variance()是var_samp()别名,var_pop()才是总体版 - 真要写可移植 SQL?放弃内置函数,改用视图封装,或在应用层用 Python/Java 算完再入库
方差本身不难,难在业务语义和数据库实现之间那层薄纸——多数人不是不会写 VAR(x),而是没意识到自己默认当成“总体”算的那组数据,其实在数据库眼里只是“样本”。











