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

数据转置(计算月度销售数据):SQL实现月度商品销售额报错求助

解决月度商品销售额行转列的SQL问题

看起来你的核心问题是没有先完成月度商品销售额的聚合计算,直接用MAX(CASE...)的逻辑不符合需求——我们需要的是每个月每个商品的销售额总和,而不是某条记录的最大值。另外你提到的GRANDTOTAL应该是计算出来的Price * Unit总和,不是表中已有的字段,这也是可能出错的点。

先理清需求逻辑

我们需要:

  • 从数据中筛选1月、2月的记录
  • 按月份(显示为Jan/Feb)分组
  • 计算每个月里jeans、skirt、shirt各自的销售额总和,以及当月总销售额

针对你的样例数据,给出适配不同数据库的SQL代码

假设你的表名为sales,日期字段是Day(格式为dd/mm/yy):

1. MySQL版本

SELECT
    -- 把字符串日期转成日期类型,再提取月份名称(Jan/Feb)
    MONTHNAME(STR_TO_DATE(Day, '%d/%m/%y')) AS Month,
    -- 计算每个商品的月度销售额总和
    SUM(CASE WHEN Item = 'jeans' THEN Price * Unit ELSE 0 END) AS jeans,
    SUM(CASE WHEN Item = 'skirt' THEN Price * Unit ELSE 0 END) AS skirt,
    SUM(CASE WHEN Item = 'shirt' THEN Price * Unit ELSE 0 END) AS shirt,
    -- 计算当月总销售额
    SUM(Price * Unit) AS Total
FROM sales
-- 只筛选1月和2月的数据
WHERE MONTH(STR_TO_DATE(Day, '%d/%m/%y')) IN (1, 2)
-- 按月份名称和月份数字分组,避免不同年份的同名月份合并,同时保证排序正确
GROUP BY MONTHNAME(STR_TO_DATE(Day, '%d/%m/%y')), MONTH(STR_TO_DATE(Day, '%d/%m/%y'))
-- 按月份顺序排序,Jan在前,Feb在后
ORDER BY MONTH(STR_TO_DATE(Day, '%d/%m/%y'));

2. SQL Server版本

SELECT
    -- 转换日期格式并提取月份名称
    DATENAME(MONTH, CONVERT(DATE, Day, 3)) AS Month,
    SUM(CASE WHEN Item = 'jeans' THEN Price * Unit ELSE 0 END) AS jeans,
    SUM(CASE WHEN Item = 'skirt' THEN Price * Unit ELSE 0 END) AS skirt,
    SUM(CASE WHEN Item = 'shirt' THEN Price * Unit ELSE 0 END) AS shirt,
    SUM(Price * Unit) AS Total
FROM sales
WHERE DATEPART(MONTH, CONVERT(DATE, Day, 3)) IN (1, 2)
GROUP BY DATENAME(MONTH, CONVERT(DATE, Day, 3)), DATEPART(MONTH, CONVERT(DATE, Day, 3))
ORDER BY DATEPART(MONTH, CONVERT(DATE, Day, 3));

3. Oracle版本

SELECT
    -- 转换日期格式并提取月份缩写
    TO_CHAR(TO_DATE(Day, 'DD/MM/RR'), 'Mon') AS Month,
    SUM(CASE WHEN Item = 'jeans' THEN Price * Unit ELSE 0 END) AS jeans,
    SUM(CASE WHEN Item = 'skirt' THEN Price * Unit ELSE 0 END) AS skirt,
    SUM(CASE WHEN Item = 'shirt' THEN Price * Unit ELSE 0 END) AS shirt,
    SUM(Price * Unit) AS Total
FROM sales
WHERE EXTRACT(MONTH FROM TO_DATE(Day, 'DD/MM/RR')) IN (1, 2)
GROUP BY TO_CHAR(TO_DATE(Day, 'DD/MM/RR'), 'Mon'), EXTRACT(MONTH FROM TO_DATE(Day, 'DD/MM/RR'))
ORDER BY EXTRACT(MONTH FROM TO_DATE(Day, 'DD/MM/RR'));

为什么你的原代码会出错?

  1. 错误使用MAX聚合函数:你需要的是销售额总和,MAX只会取某条记录的最大值,无法累加同一月份同一商品的多条销售数据。
  2. 未提前计算销售额:GRANDTOTAL不是表中字段,必须先通过Price * Unit计算单条记录的销售额,再进行聚合。
  3. 日期处理缺失:如果没有把字符串格式的Day转换成日期类型,直接按字符串分组或筛选,可能会出现逻辑错误(比如不同年份的1月被混在一起)。

运行上面的代码后,你会得到符合需求的结果:行是Jan、Feb,列包含各商品销售额和总计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:34:23