You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL单查询实现分组统计与前3日成功率均值计算

解决方案:添加前3日成功率均值列

要实现你需要的第5项需求,我们可以利用MySQL的窗口函数来计算滚动平均值,同时控制仅从第4条记录开始展示该均值。下面是改造后的完整查询语句,以及详细的逻辑说明:

完整查询代码

SELECT 
    day,
    fails,
    success,
    total,
    success_percent,
    CASE 
        WHEN row_num >= 4 THEN AVG(success_percent) OVER (ORDER BY day ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)
        ELSE NULL 
    END AS prev_3d_avg_success_percent
FROM (
    SELECT 
        day,
        fails,
        success,
        fails + success AS total,
        ROUND((success * 100 / (success + fails)), 2) AS success_percent, -- 保留两位小数优化显示
        ROW_NUMBER() OVER (ORDER BY day) AS row_num
    FROM (
        -- 你的原始统计子查询,负责计算每日基础数据
        SELECT 
            day, 
            SUM(IF(status='FAIL', 1, 0)) AS fails, 
            SUM(IF(status='SUCCESS', 1, 0)) AS success
        FROM statuses 
        GROUP BY day
    ) AS inner_query
) AS outer_query;

逻辑拆解

我们逐步来看这段代码的作用:

  • 基础统计层(inner_query):这部分就是你原本实现的逻辑,按日期分组,统计每日的失败数、成功数。
  • 中间计算层
    • 计算每日总状态数total和成功率success_percent,这里用ROUND()函数把成功率保留两位小数,让结果更整洁;
    • ROW_NUMBER() OVER (ORDER BY day)生成按日期排序的行号,方便后续判断是否是第4条及以后的记录。
  • 最终结果层
    • 使用AVG(success_percent) OVER (...)窗口函数,指定窗口范围为ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING——意思是取当前行往前数第3行到第1行的数据,正好对应前3天的成功率;
    • 通过CASE语句过滤:只有当行号≥4时,才展示前3天的平均成功率,前3条记录则显示NULL(你可以根据需求改为0或其他默认值)。

效果验证

对应你提供的测试数据,最终结果会是这样:

  • 2018-01-01、01-02、01-03这三天的prev_3d_avg_success_percentNULL
  • 2018-01-04的均值是2018-01-01、01-02、01-03三天成功率的平均值;
  • 2018-01-05的均值是2018-01-02、01-03、01-04三天成功率的平均值。

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

火山引擎 最新活动