VAR_SAMP与VAR_POP本质区别在于分母:VAR_SAMP用n−1(样本方差,适合抽样估计),VAR_POP用n(总体方差,适合全量数据);误用会导致方差低估或高估,单值分组时VAR_SAMP返回NULL、VAR_POP返回0但无统计意义。

VAR_SAMP 和 VAR_POP 的本质区别是什么
两者都算方差,但分母不同:VAR_SAMP 用的是「样本方差」公式(除以 n−1),适合从总体中抽样估算;VAR_POP 用的是「总体方差」公式(除以 n),适合你手上的数据就是完整总体的情况。
比如统计某天所有订单的金额波动,用 VAR_POP 更合理;
如果只是抽了 1000 条订单分析用户行为趋势,该用 VAR_SAMP。
常见错误是看到“方差”就默认用 VAR_SAMP,结果在报表里数值偏大——尤其当分组数据量小(比如每组只有 3–5 行)时,VAR_SAMP 会明显高估波动。
GROUP BY 场景下怎么写才不出错
直接套用 GROUP BY 即可,但要注意 NULL 和数据类型:
- 含
NULL的列参与计算时,这些行会被自动过滤(和SUM/AVG一致) - 输入列必须是数值型,否则报错:
ERROR: function var_samp(numeric) does not exist(PostgreSQL)或类似提示
示例(统计各城市订单金额的波动):
SELECT city, VAR_SAMP(order_amount) AS var_sample, VAR_POP(order_amount) AS var_pop FROM orders GROUP BY city;
别漏掉 GROUP BY ——否则会报错:column "city" must appear in the GROUP BY clause(PostgreSQL)或 nonaggregated column(MySQL 5.7+ 严格模式)。
为什么有时返回 NULL 而不是数字
三种典型情况:
- 分组内只有一行数据:此时
VAR_SAMP分母为 0(n−1=0),返回NULL;VAR_POP虽能算出值,但单点无“波动”意义,慎用 - 所有值都相同(如全为 100):
VAR_POP返回 0.0,VAR_SAMP在 n=1 时仍为NULL - 整个分组的值全为
NULL:两个函数都返回NULL
若业务上需要把单行分组的方差设为 0,得手动补:
SELECT city,
COALESCE(VAR_SAMP(order_amount), 0) AS var_sample
FROM orders
GROUP BY city;跨数据库兼容性要注意什么
- PostgreSQL、Oracle、SQL Server(2012+)都支持
VAR_SAMP 和 VAR_POP
- MySQL 8.0+ 支持,但 5.7 及之前版本不支持,只能手写:
POWER(STDDEV_SAMP(order_amount), 2) ≈ VAR_SAMP,
POWER(STDDEV_POP(order_amount), 2) ≈ VAR_POP
- SQLite 不支持这两个函数,也没内置方差,得用子查询或应用层计算
VAR_SAMP 和 VAR_POP POWER(STDDEV_SAMP(order_amount), 2) ≈ VAR_SAMP,POWER(STDDEV_POP(order_amount), 2) ≈ VAR_POP 另外,有些旧版 Hive 或 Spark SQL 默认用的是 var_samp(小写),大小写敏感时写成 VAR_SAMP 会报错。
实际用的时候,先 SELECT COUNT(*) 看看每组有多少行,再决定用哪个函数——方差本身不难,难的是搞清你手里的数据到底算“样本”还是“总体”。

















