MySQL如何按日期统计post_submit事件每日成功率
SQL修改方案
你原语句存在两个明显问题:
- SELECT子句写了
user_id但GROUP BY维度没有包含该字段,属于不规范的分组写法,才会出现单用户数据单独成行的结果 - 没有按照「忽略user_id、submit记成功、cancel记失败」的规则做日期维度的二次聚合,窗口函数算的单事件占比没有转成最终要求的成功率。
直接用条件聚合即可一步得到目标结果,不需要保留多余的窗口函数逻辑:
SELECT created_at AS dt, ROUND( SUM(CASE WHEN event_name = 'post_submit' THEN 1 ELSE 0 END) / COUNT(*) * 100, 0 ) AS `success_rate%` FROM events WHERE event_name IN ('post_submit', 'post_cancel') GROUP BY created_at ORDER BY created_at;
逻辑说明
- 过滤逻辑保留原有规则,仅统计提交成功、取消两类事件
- 用条件判断只对
post_submit类型事件计数,除以当日两类事件总条数后乘100得到成功率 - 结果保留0位小数,和期望输出的整数格式对齐
- 仅按日期分组,天然剔除user_id维度的影响;如果某日全是取消事件,分子求和为0,会自动返回0的成功率,完全匹配你给出的预期结果。
如果你需要基于你原来的子查询结构改写(比如后续还要复用中间层的事件计数逻辑),可以在外层再做一次聚合,写法如下:
SELECT created_at AS dt, ROUND( SUM(CASE WHEN event_name = 'post_submit' THEN num_of_events ELSE 0 END) / SUM(num_of_events) * 100, 0 ) AS `success_rate%` FROM ( SELECT created_at, event_name, COUNT(*) AS num_of_events FROM events WHERE event_name IN ('post_submit', 'post_cancel') GROUP BY event_name, created_at ) sub GROUP BY created_at ORDER BY created_at;
两种写法返回结果完全一致,单段聚合的写法执行效率更高。
内容的提问来源于stack exchange,提问作者jumpman8947
相关产品推荐
相关产品推荐

