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

如何计算相邻月份的销售额差值?SQL查询求助

按月汇总销售额并计算相邻月份差值的SQL修正

原始销售数据

日期销售额
3/1/2023800
3/2/2023300
3/3/2023500
4/1/2023300
4/2/2023500
4/3/2023200
5/1/2023100
5/2/2023400
5/3/2023400

期望输出结果

日期销售额差值
5/1/2023900100
4/1/20231000600
3/1/202316000

现有查询语句

SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0) AS TrendStartDate,
       SUM(Sales) AS TotalSales ,
       LEAD(SUM(Sales), 1) OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0)
ORDER BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0) DESC) AS Sales_diff 
FROM salestable
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0)
ORDER BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0) ASC

问题分析

原查询存在两个核心问题:

  1. 错误的分区设置:PARTITION BY DATEADD(...)会将每个单独的月份作为一个分区,导致LEAD函数无法跨月份获取相邻值,每个分区仅一行数据,LEAD返回NULL。
  2. 排序与差值逻辑不匹配:原查询按日期升序排列,未实现“当前月销售额 - 下月销售额”的计算逻辑,也未处理最老月份的差值默认值。

修正后的查询语句

WITH MonthlySales AS (
    -- 按月汇总销售额,得到每个月的起始日期和总销售额
    SELECT 
        DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0) AS TrendStartDate,
        SUM(Sales) AS TotalSales
    FROM salestable
    GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Salesdate), 0)
)
SELECT 
    -- 转换日期格式为MM/DD/YYYY,匹配期望输出
    CONVERT(VARCHAR(10), TrendStartDate, 101) AS 日期,
    TotalSales AS 销售额,
    -- 计算当前月与下月的销售额差值,最老月份差值设为0
    ISNULL(TotalSales - LEAD(TotalSales) OVER (ORDER BY TrendStartDate DESC), 0) AS 差值
FROM MonthlySales
-- 按日期降序排列,得到期望的输出顺序
ORDER BY TrendStartDate DESC;

修正说明

  • 用CTE拆分逻辑,先完成按月汇总,再计算差值,提升代码可读性。
  • 移除PARTITION BY,让LEAD在所有月份的结果集中生效,正确获取相邻月份的销售额。
  • 通过ORDER BY TrendStartDate DESC让LEAD返回下一个更早的月份销售额,结合TotalSales - LEAD(...)得到所需差值。
  • 用ISNULL处理无后续月份的情况,将差值设为0。
  • 转换日期格式以匹配期望输出样式,最终按日期降序排列结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:40:00