MySQL查询生成月度出库商品报表 含当年未出库商品库存数据
MySQL月度商品出库报表问题解决方案
问题根因
原有写法的核心问题是YEAR(Issue_Date) = 2021写在WHERE全局过滤条件中,会直接筛掉2021年无出库记录的商品;如果移除WHERE条件,往年的出库记录又会被统计到对应月份的汇总结果中。
实现方案
方案1:聚合逻辑内嵌年份判断(简单易改)
直接将年份校验放到CASE统计逻辑内,去掉全局WHERE过滤,即可保留所有商品数据,且仅统计2021年的出库量:
SELECT Product, MAX(Stock) AS Stock, SUM(CASE WHEN YEAR(Issue_Date) = 2021 AND MONTH(Issue_Date) = 1 THEN `Issue_Qty` END) jan, SUM(CASE WHEN YEAR(Issue_Date) = 2021 AND MONTH(Issue_Date) = 2 THEN `Issue_Qty` END) feb, SUM(CASE WHEN YEAR(Issue_Date) = 2021 AND MONTH(Issue_Date) = 3 THEN `Issue_Qty` END) mar, -- 依次补全4-11月的统计逻辑 SUM(CASE WHEN YEAR(Issue_Date) = 2021 AND MONTH(Issue_Date) = 12 THEN `Issue_Qty` END) `December` FROM product GROUP BY Product ORDER BY Product ASC
方案2:左关联预过滤出库数据(性能更优,大表推荐)
如果出库历史数据量较大,先预过滤2021年的出库记录再关联全量商品基础信息,执行效率更高:
SELECT base.Product, base.Stock, SUM(CASE WHEN MONTH(issue.Issue_Date) = 1 THEN issue.`Issue_Qty` END) jan, SUM(CASE WHEN MONTH(issue.Issue_Date) = 2 THEN issue.`Issue_Qty` END) feb, SUM(CASE WHEN MONTH(issue.Issue_Date) = 3 THEN issue.`Issue_Qty` END) mar, -- 依次补全4-11月的统计逻辑 SUM(CASE WHEN MONTH(issue.Issue_Date) = 12 THEN issue.`Issue_Qty` END) `December` FROM ( -- 提取全量商品基础信息,保证无出库记录的商品不会丢失 SELECT DISTINCT Product, Stock FROM product ) base LEFT JOIN product issue ON base.Product = issue.Product AND YEAR(issue.Issue_Date) = 2021 -- 年份限制写在关联条件中,不会过滤无出库记录的商品 GROUP BY base.Product, base.Stock ORDER BY base.Product ASC
补充说明
- 两种方案均会保留所有商品条目,仅统计2021年的出库量,无出库记录的月份默认返回NULL(即需要的留空效果)。如果需要无出库时显示为0,可在SUM函数外套用
IFNULL(你的SUM逻辑, 0)即可。 - 若
product表中每个商品对应唯一的Stock记录,方案2子查询中的DISTINCT可以直接去掉。
内容的提问来源于stack exchange,提问作者Ripon
相关产品推荐
相关产品推荐

