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

SQL月度产品累计增长报表查询需求及问题求助

按公司统计月度累计产品数量的SQL查询问题

需求说明:

  • 生成月度增长报表,按公司统计各年月度累计产品数量:若某公司上月累计产品数为4,本月新增1,则上月显示4,本月显示5(上月累计值+本月新增值),需覆盖所有年份。

现有问题:
已编写查询可按公司、年份、月份统计当月产品新增数量,但尝试用lag函数实现累计时结果不符合预期,需要实现同公司内1月累计值累加到2月,2月累计值再累加到3月的连续累加逻辑。

原始查询代码:

SELECT * FROM (
    SELECT 
        c.Name,
        YEAR(p.DateAdded) [Year], 
        DATENAME(MONTH, p.DateAdded) [Month], 
        COUNT(ProductID)--+lag(COUNT(p.ProductID),1) OVER ( ORDER BY YEAR(p.DateAdded),DATENAME(MONTH, p.DateAdded)) ProductCount 
    FROM Product.Product p 
    LEFT JOIN (SELECT ID,name from sourcing.Company WHERE CompanyTypeID=1 AND DateDeleted IS null) c 
        ON p.ManufacturerID=c.id 
    WHERE p.DateArchived IS NULL AND p.ManufacturerID=571 AND YEAR(p.DateAdded) IN ('2015') 
    GROUP BY c.Name,YEAR(p.DateAdded), DATENAME(MONTH, p.DateAdded)
) AS MontlySalesData 
ORDER BY MontlySalesData.Year,MontlySalesData.Month

当前查询结果:

公司年份月份产品数量
Company12022一月5
Company12022二月6
Company22022一月5
Company22022二月6
Company32022一月5
Company32022二月6

预期结果:

公司年份月份产品数量
Company12022一月5
Company12022二月11
Company22022一月5
Company22022二月11
Company32022一月5
Company32022二月11
Company32022三月13
Company32022四月50

解决方案:使用SUM窗口函数实现累计计算

lag函数只能获取上一行的单个值,无法实现连续累加,正确的做法是使用SUM() OVER()窗口函数,按公司分区、按年月排序来计算累计值。

修改后的查询代码:

SELECT 
    Name AS 公司,
    [Year] AS 年份,
    DATENAME(MONTH, DATEFROMPARTS([Year], MonthNum, 1)) AS 月份,
    CumulativeProductCount AS 产品数量
FROM (
    SELECT 
        c.Name,
        YEAR(p.DateAdded) AS [Year],
        MONTH(p.DateAdded) AS MonthNum, -- 用数字月份保证排序正确
        COUNT(p.ProductID) AS MonthlyAddition,
        -- 按公司分区,按年份、数字月份排序,计算累计值
        SUM(COUNT(p.ProductID)) OVER (
            PARTITION BY c.Name 
            ORDER BY YEAR(p.DateAdded), MONTH(p.DateAdded)
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS CumulativeProductCount
    FROM Product.Product p 
    LEFT JOIN (
        SELECT ID, name 
        FROM sourcing.Company 
        WHERE CompanyTypeID=1 AND DateDeleted IS NULL
    ) c ON p.ManufacturerID = c.id 
    WHERE p.DateArchived IS NULL 
    -- 移除单公司、单年份限制,覆盖所有公司和年份
    GROUP BY c.Name, YEAR(p.DateAdded), MONTH(p.DateAdded)
) AS MonthlyData
ORDER BY 公司, 年份, MonthNum

关键说明:

  1. 按公司分区:PARTITION BY c.Name确保累计计算仅在同公司内进行,不会跨公司累加。
  2. 用数字月份排序:使用MONTH(p.DateAdded)获取数字月份,避免DATENAME返回的月份字符串排序错误(比如"十月"会排在"二月"之前)。
  3. 累计窗口范围:ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW明确指定从当前分区的第一行到当前行进行累加,这是窗口函数累计的默认行为,显式写出更清晰。
  4. 移除不必要的筛选:原查询中的ManufacturerID=571和YEAR(p.DateAdded) IN ('2015')限制了数据范围,若要覆盖所有公司和年份需移除。

执行该查询后,结果将符合预期的累计逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:12:05