如何通过SQL计算分组数据的方差与标准差_利用VAR_SAMP与STDDEV函数

落静同学_9462

落静同学_9462

2026-04-23

666人浏览

原创

VAR_SAMP和STDDEV是计算样本方差和样本标准差的聚合函数,分母为n−1,适用于推断统计;STDDEV通常是STDDEV_SAMP的别名。

如何通过sql计算分组数据的方差与标准差_利用var_samp与stddev函数

VAR_SAMP 和 STDDEV 是什么函数?它们算的是总体还是样本?

VAR_SAMP 和 STDDEV(或等价的 STDDEV_SAMP)是 SQL 标准中用于计算**样本方差**和**样本标准差**的聚合函数。注意:它们默认按「样本」处理,即分母为 n−1,不是 n。如果你误用它们去算「总体方差」,结果会偏大——尤其在小数据集上偏差明显。

常见错误现象:SELECT VAR_SAMP(score) FROM students 返回值比 Excel 的 VAR.S 一致,但和 VAR.P 不同;若你本意是描述整个班级(无抽样),该用 VAR_POP 和 STDDEV_POP。

  • 样本类函数(推荐用于推断统计):VAR_SAMP、STDDEV_SAMP、STDDEV(多数数据库中 STDDEV 是 STDDEV_SAMP 的别名)
  • 总体类函数(适合全量数据描述):VAR_POP、STDDEV_POP
  • PostgreSQL / Oracle / MySQL 8.0+ / SQL Server 2022+ 都支持;SQLite 不支持,需手写公式

如何在 GROUP BY 中正确使用 VAR_SAMP 计算每组方差?

直接套用即可,但要注意 NULL 值会被自动忽略——这通常合理,但若字段本应非空却含 NULL,会导致组内有效计数 n 比预期小,进而影响 n−1 分母的稳定性。

SELECT 
  dept,
  COUNT(*) AS total_cnt,
  COUNT(score) AS non_null_cnt,
  VAR_SAMP(score) AS var_sample,
  STDDEV(score) AS stddev_sample
FROM employees
GROUP BY dept;

使用场景:分析各部门绩效分数离散程度。若某部门 non_null_cnt ,<code>VAR_SAMP 返回 NULL(因无法计算样本方差),这是正确行为,不是 bug。

  • 确保分组字段与聚合字段逻辑自洽(例如不能对时间维度分组后,再对非时序稳定的指标算方差)
  • 若需过滤掉方差过小的组,可在 HAVING 中写 HAVING VAR_SAMP(score) > 0.1,但注意 NULL 不参与比较
  • MySQL 5.7 及更早版本不支持窗口化 VAR_SAMP,如需组内标准化(z-score),得用子查询或变量模拟

为什么 STDDEV 返回值和手动 SQRT(VAR_SAMP(x)) 不完全相等?

浮点精度差异。虽然数学上 STDDEV(x) = SQRT(VAR_SAMP(x)),但数据库内部实现可能采用单程算法(如 Welford 方法)来同步计算均值与方差,减少累积误差;而两步写法 SQRT(VAR_SAMP(x)) 先算方差再开方,中间多一次舍入。

实测差异通常在 1e-13 量级,不影响业务判断,但在做单元测试断言或审计比对时,建议统一用原生函数而非手算。

  • Oracle 和 PostgreSQL 对 STDDEV 和 SQRT(VAR_SAMP()) 的结果做了对齐,基本一致
  • MySQL 8.0 在某些边界值(如全相同数字)下,STDDEV 可能返回 -0.0,而 SQRT(VAR_SAMP()) 返回 0.0
  • 如需最大一致性,且数据库支持,优先用 STDDEV_SAMP 而非别名 STDDEV

没有 VAR_SAMP 的旧数据库(如 MySQL 5.6)怎么替代?

只能手写公式:VAR_SAMP = (SUM(x*x) - SUM(x)*SUM(x)/COUNT(x)) / (COUNT(x) - 1)。注意括号顺序和类型转换——整数除法会导致截断。

SELECT 
  dept,
  (SUM(score*score) - SUM(score)*SUM(score)/COUNT(score)) / (COUNT(score) - 1) AS var_samp_manual
FROM employees
WHERE score IS NOT NULL
GROUP BY dept
HAVING COUNT(score) > 1;

容易踩的坑:

  • 漏加 HAVING COUNT(score) > 1,导致除零错误
  • 没写 WHERE score IS NOT NULL,让 SUM 返回 NULL,整行失效
  • SUM(score)*SUM(score) 可能溢出(尤其 score 是 BIGINT 且组很大),可改用 AVG 拆解:先算均值,再算平方偏差均值 × n/(n−1)

这种写法性能不如原生函数,且不可移植;一旦升级数据库,应尽快切回 VAR_SAMP。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4523

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

951

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1189

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6501

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3263

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6460

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8861

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1210

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1052

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134万人学习