You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL中如何实现每3行数据计算一次平均值?

每3行计算平均值规则示意图

SQL实现每3行计算平均值方案

SQL中表本身是无序集合,所以所有计算的前提是先指定明确的排序字段(比如自增主键、业务时间戳),否则行顺序不确定,计算结果没有意义。下面分两种最常见的需求场景给出可直接复用的代码:


场景1:滚动计算连续3行的平均值

即每一行的结果为「当前行+前2行」的均值,前2行不足3行时按实际存在的行数计算,适合做趋势平滑场景。
支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle、Hive、Spark SQL等)直接用窗口函数实现,性能最好:

SELECT
  *,
  AVG(要计算均值的数值字段) OVER (
    ORDER BY 你的排序字段 -- 替换为实际的排序字段,比如id、stat_time
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ) AS rolling_avg_3rows
FROM 你的业务表名;

如果要求必须凑够3行才返回结果,不足3行的前两行返回空,加个行号判断即可:

SELECT
  *,
  CASE WHEN ROW_NUMBER() OVER (ORDER BY 你的排序字段) >= 3
       THEN AVG(要计算均值的数值字段) OVER (
         ORDER BY 你的排序字段
         ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
       )
  END AS rolling_avg_3rows
FROM 你的业务表名;

场景2:每3行分为固定一组,计算组内平均值

即第1-3行为第一组、4-6行为第二组,以此类推,同组所有行共享同一个平均值。
支持窗口函数的数据库写法:

WITH ranked_table AS (
  SELECT
    *,
    ROW_NUMBER() OVER (ORDER BY 你的排序字段) AS row_num
  FROM 你的业务表名
)
SELECT
  *,
  AVG(要计算均值的数值字段) OVER (PARTITION BY CEIL(row_num / 3)) AS group_avg_3rows
FROM ranked_table;

如果是MySQL 5.x这类不支持窗口函数的老版本,用用户变量生成行号后关联计算即可:

SELECT
  t1.*,
  AVG(t2.要计算均值的数值字段) AS group_avg_3rows
FROM (
  SELECT
    @rn := @rn + 1 AS row_num,
    -- 此处替换为你实际需要查询的字段
    id, stat_time, value
  FROM 你的业务表名, (SELECT @rn := 0) init
  ORDER BY 你的排序字段
) t1
INNER JOIN (
  SELECT
    @rn2 := @rn2 + 1 AS row_num,
    要计算均值的数值字段
  FROM 你的业务表名, (SELECT @rn2 := 0) init
  ORDER BY 你的排序字段
) t2 ON CEIL(t2.row_num / 3) = CEIL(t1.row_num / 3)
GROUP BY t1.row_num, t1.id, t1.stat_time, t1.value;

替换代码参数时注意:排序字段必须是能唯一确定行顺序的非空字段,不要用有重复值的字段排序,否则会出现行号重复、计算偏差的问题。


内容的提问来源于stack exchange,提问作者ignesiyasLoyala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:39:13