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

MySQL按商品统计每月销售数量:SQL结果异常求助

解决SQL分组统计每月销量的异常问题

嘿,我一眼就看出你遇到的问题根源了!你的SQL里SUM()函数的位置摆错了,导致它计算的是每个商品的总销量,而不是对应月份的销量。

问题出在哪?

先看你原来的SQL:

SELECT `sales`.`item_id`, 
       (CASE WHEN MONTH(sales.date)=1 THEN sum(sales.item_count) ELSE NULL END) as JAN, 
       (case when MONTH(sales.date)=2 THEN sum(sales.item_count) ELSE NULL END) as FEB 
FROM sales 
WHERE 1 
GROUP BY sales.item_id 
ORDER BY sales.item_id;

这里的SUM(sales.item_count)是对整个item_id分组的所有行求和,然后CASE WHEN只是判断这个分组里有没有1月的数据——如果有,就把总销量塞进JAN列,否则放NULL。这就导致你看到的JAN列是该商品的全部销量,FEB列变成NULL(因为分组里同时有1月和2月数据时,第一个CASE满足,第二个不触发)。

正确的写法

你需要把SUM()放到CASE WHEN的内部,让它只对符合月份条件的行的item_count求和:

SELECT 
    item_id,
    SUM(CASE WHEN MONTH(date) = 1 THEN item_count ELSE 0 END) AS JAN,
    SUM(CASE WHEN MONTH(date) = 2 THEN item_count ELSE 0 END) AS FEB
FROM sales
GROUP BY item_id
ORDER BY item_id;

简单解释:

  • 对每个item_id分组,CASE WHEN MONTH(date)=1 THEN item_count ELSE 0 END会保留1月份行的item_count,其他月份的行贡献0。
  • 外层的SUM()把这些值加起来,就得到了该商品1月份的真实销量,FEB列同理。
  • 用ELSE 0代替ELSE NULL的好处是,没有对应月份销量时会显示0,而不是NULL,结果更直观。

测试结果

用你的测试数据运行这个SQL,会完美得到你期望的结果:

item_idJANFEB
1117
253

扩展:跨年份的兼容写法

如果你的数据涉及多个年份,建议加上年份判断,避免把不同年份的同月份数据混在一起:

SELECT 
    item_id,
    YEAR(date) AS sale_year,
    SUM(CASE WHEN MONTH(date) = 1 THEN item_count ELSE 0 END) AS JAN,
    SUM(CASE WHEN MONTH(date) = 2 THEN item_count ELSE 0 END) AS FEB
FROM sales
GROUP BY item_id, YEAR(date)
ORDER BY item_id, sale_year;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:58:55