VAR_SAMP更适合质量控制场景,因其用n−1作分母提供总体方差的无偏估计,避免因抽样导致控制限过窄而误判;而VAR_POP假设全量数据,用于抽检会低估变异。

VAR_SAMP 为什么比 VAR_POP 更适合质量控制场景
质量控制通常基于抽样检测(比如每批次抽检10件产品),而非测量全部个体。VAR_SAMP 使用 n−1 自由度分母,给出的是对总体方差的无偏估计;而 VAR_POP 假设你拥有全部数据,会低估真实变异程度。用错会导致控制限过窄,误判合格品为异常。
常见错误现象:SELECT VAR_POP(measurement) FROM qc_data WHERE batch_id = 'B2024-05' —— 这实际在计算该批次“全量数据”的方差,但如果你只录入了抽检值,结果就失真了。
- 必须确保输入是样本(即非全量数据),否则无偏性失去意义
- 当样本量
n < 2时,VAR_SAMP返回NULL(数学上无法定义),需提前过滤或加HAVING COUNT(*) > 1 - 某些旧版 MySQL(如 5.6)不支持
VAR_SAMP,需升级或改用POWER(STDDEV_SAMP(x), 2)替代
带条件和分组的质量控制方差计算实操
真实产线中,你要对比不同班次、设备或原料批次的波动性。直接套用 VAR_SAMP 即可,但要注意 NULL 和分组逻辑。
示例:计算各设备在上周的尺寸测量值样本方差
SELECT equipment_id, VAR_SAMP(measure_value) AS sample_variance, AVG(measure_value) AS mean_value, COUNT(*) AS sample_size FROM qc_records WHERE measure_time >= '2024-06-01' AND measure_time < '2024-06-08' AND measure_value IS NOT NULL GROUP BY equipment_id HAVING COUNT(*) > 1;
-
WHERE ... IS NOT NULL必须显式排除 NULL,VAR_SAMP会自动跳过 NULL,但若整组全为 NULL 就返回 NULL,不易排查 -
HAVING COUNT(*) > 1防止单条记录触发除零错误(虽然 SQL 标准定义此时返回 NULL,但部分驱动可能报错) - 别名建议用
sample_variance而非variance,避免和VAR_POP或业务字段混淆
与控制图(X̄-S 图)结合时的数值校验要点
在构建 S 控制图(标准差图)时,常需先算样本标准差 S,而 STDDEV_SAMP 是 SQRT(VAR_SAMP(...)) 的等价写法。但注意:控制图系数(如 B3/B4)依赖子组大小 n,不能把所有子组混在一起算一个 VAR_SAMP。
- 错误做法:
VAR_SAMP(measure_value) OVER()—— 这会跨子组混算,破坏统计过程控制前提 - 正确做法:每个子组(如每小时 5 个样本)单独聚合,再用
AVG()对各子组的VAR_SAMP值求均值,得到平均样本方差\bar{S^2} - 若子组大小不一致(如有的 4 个、有的 6 个),
VAR_SAMP仍可用,但控制限公式需查对应表,不能硬套固定系数
PostgreSQL / Oracle / SQL Server 中的兼容性差异
语法一致,但默认行为和 NULL 处理略有不同:
- PostgreSQL:严格遵循 SQL 标准,
VAR_SAMP在空组返回NULL,且支持窗口用法VAR_SAMP(x) OVER (PARTITION BY shift) - Oracle:同 PostgreSQL,但若启用
EMPTY_GROUPING_SETS,需额外处理空分组 - SQL Server:从 2012 起支持,但
VAR_SAMP是别名,底层调用VAR函数(注意不是VARIANCE,后者是VAR_POP) - BigQuery:使用
VAR_SAMP(),但字段必须显式转为数值型,STRING类型会静默失败
跨平台迁移时,最易被忽略的是子查询中未加 HAVING 导致单样本组返回 NULL,后续做 SQRT() 或除法时报错 —— 这类问题在线上环境往往只在特定小批量数据中暴露。

















