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

MySQL中生成年度季度报表并按季度求和的查询问题排查

解决MySQL年度季度报表按季度求和的问题

我来帮你梳理下当前SQL的问题,然后给出更靠谱的解决方案:

原SQL的核心问题

  • 月份条件逻辑错误:你用AND连接多个月份(比如bl.month = 'January' and bl.month = 'Feburary'),这永远匹配不到任何数据——一条记录的月份不可能同时等于两个不同值,应该用IN或者OR
  • 重复关联导致笛卡尔积:多次LEFT JOIN同一张bldetails表,会让数据行重复膨胀,最终SUM出来的结果会远大于实际值
  • 冗余条件+拼写错误:存在重复的月份判断,还有Feburary的拼写错误(正确是February)

优化后的解决方案:使用条件聚合

不需要多次关联表,直接在SUM里用CASE WHEN判断记录所属季度,这样既简洁又不会出现数据重复计算的问题:

SELECT 
    t.name as terminals,
    SUM(CASE WHEN bl.month IN ('January', 'February', 'March') THEN bl.barrels_net_qty ELSE 0 END) as '1ST QTR',
    SUM(CASE WHEN bl.month IN ('April', 'May', 'June') THEN bl.barrels_net_qty ELSE 0 END) as '2ND QTR',
    SUM(CASE WHEN bl.month IN ('July', 'August', 'September') THEN bl.barrels_net_qty ELSE 0 END) as '3RD QTR',
    SUM(CASE WHEN bl.month IN ('October', 'November', 'December') THEN bl.barrels_net_qty ELSE 0 END) as '4TH QTR',
    SUM(COALESCE(bl.barrels_net_qty, 0)) as total
FROM loadingdetails as l
LEFT JOIN bldetails as bl 
    ON bl.operation_no = l.operation_no 
    AND l.year = '2020'
LEFT JOIN terminals as t 
    ON t.id = l.terminal_id
WHERE l.year = '2020' -- 统一过滤2020年的数据,也可以放在JOIN条件里
GROUP BY t.name;

代码说明

  1. 条件聚合:通过CASE WHEN把每个季度的月份归组,只对对应季度的barrels_net_qty求和,自动忽略其他季度的数据
  2. 避免笛卡尔积:只关联一次bldetails表,不会产生数据行重复的问题
  3. 简化逻辑:把年份条件统一处理,避免重复写在多个JOIN里
  4. Total计算简化:直接对所有非空的barrels_net_qty求和,和四个季度的和结果一致,更简洁

如果你的month字段是数字类型(比如1-12),可以把判断改成bl.month BETWEEN 1 AND 3这种形式,效率会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:12:45