主流数据库中标准差函数为stddev_pop/stddev_samp(或别名stddev),方差函数为var_pop/var_samp(或别名variance);前者用总体公式(除以n),后者用样本公式(除以n−1)。

SQL标准差与方差函数名是什么
主流数据库中,标准差和方差有两套函数:带 STDDEV / VAR 前缀的(如 STDDEV_POP、VAR_SAMP),以及别名形式(如 PostgreSQL 支持 stddev() 小写函数)。关键区别在于分母:
- STDDEV_POP 和 VAR_POP 用总体公式(除以 N)
- STDDEV_SAMP 和 VAR_SAMP 用样本公式(除以 N−1),这也是 Excel 的 STDEV.S 和多数统计工具默认行为
MySQL 8.0+、PostgreSQL、SQL Server(2012+)、Oracle 都支持这四组函数;SQLite 只有 stddev()(即样本标准差)和 variance()(样本方差),不区分 POP/SAMP。
GROUP BY 中直接使用聚合函数的写法
标准差和方差是聚合函数,必须配合 GROUP BY 使用,不能混在非聚合字段里——否则会报错,比如 SELECT dept, salary, STDDEV_SAMP(salary) FROM emp GROUP BY dept 是非法的,因为 salary 未聚合也未出现在 GROUP BY 中。
正确写法示例(按部门计算薪资的标准差与方差):
SELECT dept, COUNT(*) AS cnt, ROUND(AVG(salary), 2) AS avg_salary, ROUND(STDDEV_SAMP(salary), 2) AS stddev_salary, ROUND(VAR_SAMP(salary), 2) AS var_salary FROM emp GROUP BY dept ORDER BY cnt DESC;
注意点:
-
STDDEV_SAMP和VAR_SAMP要求组内至少 2 行数据,否则返回NULL(单行无法算样本标准差) - 若某组只有 1 行,而你又需要一个数值,可改用
STDDEV_POP,它对单行返回 0 - 所有值为
NULL的行会被自动忽略,但整组全NULL时结果仍是NULL
不同数据库对 NULL 和空组的处理差异
SQL 标准规定聚合函数自动跳过 NULL,但空组(如 LEFT JOIN 后无匹配行)的行为容易被忽略:
- PostgreSQL:空组产生一行
NULL值(例如SELECT dept, STDDEV_SAMP(salary) FROM dept LEFT JOIN emp USING(dept) GROUP BY dept中,没有员工的部门会显示NULL的标准差) - MySQL:同样返回
NULL,但若启用了sql_mode=STRICT_TRANS_TABLES,某些旧版本可能报错 - SQL Server:空组下
STDEV返回NULL,但要注意STDEV默认等价于STDEV_SAMP,不是STDEV_POP
如果业务上需把空组/单行组显式标为 0,得用 CASE WHEN COUNT(*) 包一层。
性能与精度注意事项
标准差和方差计算需要两遍扫描:第一遍算均值,第二遍算平方偏差和。这意味着:
- 大数据量下比
COUNT或AVG更耗资源,尤其在没索引的分组字段上 - 浮点精度误差不可避免,特别是当数值范围大、差异小时(如百万级均值下微小波动),建议用
DECIMAL类型列或在应用层后处理 - 某些数据库(如 Redshift)不支持
VAR_SAMP,只提供STDDEV(即样本标准差),方差需手动写成POWER(STDDEV(col), 2)
跨库移植时,别假设 STDDEV 一定存在——先查文档,再用条件聚合兜底更稳妥。











