在业务数据分析中,我们常常需要判断某个企业、某个产品或者某个用户的指标表现是否优于行业整体水平,这就需要把当前数据和行业平均水平放在一起做对比。使用AVG窗口函数可以高效完成这个需求,不需要额外的表关联操作。

AVG窗口函数基础语法
AVG窗口函数是SQL中窗口函数的一种,用于计算指定窗口范围内的平均值,基本语法如下:
AVG(需要计算平均值的列) OVER (
[PARTITION BY 分组列]
[ORDER BY 排序列 [ASC|DESC]]
[窗口范围]
)
其中PARTITION BY用来指定分组的维度,比如按行业分组的话,就会在每个行业内部单独计算平均值;ORDER BY用来指定排序规则,部分场景下需要按时间等维度排序后再计算滑动平均;窗口范围用来指定计算平均值的行范围,不指定的话默认计算当前分组内的所有行。
对比当前数据与行业平均水平的实现步骤
假设我们有一张企业营收数据表enterprise_revenue,表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| enterprise_id | INT | 企业ID |
| industry | VARCHAR | 所属行业 |
| revenue | DECIMAL | 年度营收(万元) |
现在需要查询每个企业的营收,同时展示对应行业的平均营收,并且标注该企业的营收是否高于行业平均。
第一步:计算行业平均营收
使用AVG窗口函数按行业分组计算平均营收,代码如下:
SELECT
enterprise_id,
industry,
revenue,
-- 按行业分组计算平均营收
AVG(revenue) OVER (PARTITION BY industry) AS industry_avg_revenue
FROM enterprise_revenue;
这段查询会保留原表的所有行,同时新增industry_avg_revenue列,每个企业对应的该列值就是其所属行业的所有企业营收平均值。
第二步:对比当前数据与行业平均
基于上一步的查询结果,我们可以进一步判断每个企业的营收是否高于行业平均,完整代码如下:
SELECT
enterprise_id,
industry,
revenue,
industry_avg_revenue,
-- 判断当前营收是否高于行业平均
CASE
WHEN revenue > industry_avg_revenue THEN '高于行业平均'
WHEN revenue = industry_avg_revenue THEN '等于行业平均'
ELSE '低于行业平均'
END AS revenue_compare_result
FROM (
SELECT
enterprise_id,
industry,
revenue,
AVG(revenue) OVER (PARTITION BY industry) AS industry_avg_revenue
FROM enterprise_revenue
) t;
使用注意事项
- AVG窗口函数计算平均值时会自动忽略NULL值,如果某列存在NULL,需要提前用
COALESCE函数处理,避免影响平均结果准确性。 - 如果只需要计算整体行业的平均,不需要按行业分组,可以省略
PARTITION BY子句,此时窗口会覆盖所有行,计算全量数据的平均值。 - 窗口函数的执行顺序在WHERE、GROUP BY之后,所以如果需要对数据做过滤,要先在子查询或者CTE中完成过滤,再使用窗口函数计算平均值。
总结
使用AVG窗口函数对比当前数据与行业平均水平,相比传统的先聚合再关联的方式,代码更简洁,执行效率也更高。只需要通过PARTITION BY指定行业分组维度,就能直接在原数据行上得到行业平均数值,后续可以灵活做各种对比分析。掌握这个技巧可以大幅提升日常数据分析的效率,适合各类需要分组对比平均值的场景。