var函数在分组统计中直接可用,但默认计算样本方差(n−1),需用var_pop计算总体方差;自动忽略null,全null或仅一个非空值时var_samp返回null、var_pop返回0.0。

VAR函数在分组统计中直接可用,但要注意NULL和样本/总体的区别
SQL标准中的 VAR(或更常见的别名 VAR_SAMP)是专为分组内方差计算设计的聚合函数,无需手动实现平方差求和。但它默认计算的是**样本方差**(除以 n−1),不是总体方差(除以 n)。如果业务要求“整个分组视为总体”,得改用 VAR_POP,否则结果会系统性偏高。
-
VAR和VAR_SAMP等价,适用于从分组中抽样推断更大总体的场景 -
VAR_POP适用于该分组就是全部数据、不外推的场景(如统计某日各门店销售额的离散程度) - 所有
VAR*函数会自动忽略NULL值;若整组全为NULL或仅一个非空值,VAR_SAMP返回NULL,VAR_POP返回0.0
GROUP BY + VAR 的基本写法和常见报错
直接在 SELECT 中对数值列使用 VAR(),配合 GROUP BY 即可完成分组方差统计。最容易出错的是:把非分组列又没套聚合函数,或者误对字符串/布尔列调用 VAR()。
- 正确写法:
SELECT dept, VAR(salary) AS salary_var FROM employees GROUP BY dept - 错误现象:
ERROR: column "employees.name" must appear in the GROUP BY clause or be used in an aggregate function—— 检查SELECT列表里是否有未聚合也未出现在GROUP BY中的列 - 错误现象:
ERROR: function var(text) does not exist—— 确保传入VAR()的是数值型列(INT、FLOAT、NUMERIC),必要时加::numeric强转
MySQL / PostgreSQL / SQL Server 对VAR的支持差异
语法一致,但函数名和默认行为有区别,跨数据库迁移时容易踩坑。
- PostgreSQL:支持
VAR()、VAR_SAMP()、VAR_POP()全套,VAR()是VAR_SAMP()的同义词 - MySQL:只提供
VARIANCE()(=VAR_SAMP())和VAR_POP();没有VAR()这个简写,用会报错 - SQL Server:用
VAR()表示样本方差,VARP()表示总体方差;注意不是VAR_POP - SQLite:不支持任何方差函数,必须手写
(AVG(x*x) - AVG(x)*AVG(x))(仅当无 NULL 时数学等价)
方差为NULL或0时该怎么排查
返回 NULL 不一定代表出错,要结合分组数据结构判断;而 0 可能掩盖了真实问题。
-
NULL结果常见原因:分组内少于 2 个非空值(VAR_SAMP要求 n ≥ 2)、整组全NULL、或列类型隐式转换失败(如字符串含非数字字符) -
0结果不一定代表完全无波动:若所有值相等,方差为 0;但也要防“假相等”——比如salary是INT类型,实际小数部分被截断,导致方差失真 - 快速验证:对可疑分组补查
COUNT(*)、COUNT(col)、MIN(col)、MAX(col),确认数据量与取值范围
方差本身对异常值敏感,如果分组内存在明显离群点,VAR 值会被大幅拉高,此时看标准差或四分位距可能更稳;另外,所有数据库的 VAR 都不支持窗口模式(即不能写 VAR(x) OVER (PARTITION BY ...)),需要改用 STDDEV 配合平方,或借力 CTE 预聚合。











