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

SQL Server动态获取最近3个月数据:现有TOP查询问题求助

问题分析与解决方案

问题背景

需要在SQL Server报表中动态获取最近3个月的汇总数据(无需硬编码指定月份),预期返回最近3个完整月份的分组统计结果(如数据中最新月份为2025年2月时,返回2024年12月、2025年1月、2025年2月的数据)。

测试表创建代码:

CREATE TABLE myTable(id int, area varchar(20), myDate DATE, Qty int);
INSERT INTO myTable ([id],[area],[myDate],[Qty])
VALUES
(1,'Shipping','2024-12-24',3),
(2,'IT','2024-12-15', 5),
(3,'Shipping','2024-12-26',6),
(4,'HR','2024-12-28',2),
(5,'IT','2024-12-30',1),
(6,'Shipping','2025-01-01',2),
(7,'Shipping','2025-01-03',1),
(8,'Shipping','2025-02-01',2),
(9,'Shipping','2024-11-28',1);

现有查询的错误

  • 使用TOP(3)配合ORDER BY 1,2 ASC时,会返回数据中最早的3个月份,而非最近的3个,因此得到了2024年11月、12月及2025年1月的数据,不符合需求。
  • 使用TOP(3)配合ORDER BY 1,2 DESC时,虽然能获取到包含最近月份的分组,但排序为倒序,且错误包含了更早的2024年11月数据——核心问题是没有精准筛选出最近3个完整月份的范围,仅通过分组后取前3条的逻辑无法满足需求。

正确实现方案

核心思路

先通过日期计算确定最近3个完整月份的时间范围,再筛选该范围内的数据进行分组汇总,最后按年月正序排列结果。

方案1:基于系统当前日期获取最近3个完整月份

该方案会根据SQL Server的当前系统日期,自动计算最近3个已结束的完整月份(例如当前为2025年3月时,返回2025年2月、1月及2024年12月的数据):

WITH DateRange AS (
    SELECT
        -- 计算当前月份第一天,再往前推3个月作为筛选起始点
        DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 3, 0) AS StartDate,
        -- 计算当前月份第一天作为筛选结束点(不包含当前月)
        DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) AS EndDate
),
MonthlySummary AS (
    SELECT
        YEAR(myDate) AS [Year],
        MONTH(myDate) AS [Month],
        DATENAME(MONTH, myDate) AS [Month Name],
        SUM(Qty) AS [Total]
    FROM myTable
    CROSS JOIN DateRange
    WHERE area = 'Shipping'
      AND myDate >= StartDate
      AND myDate < EndDate
    GROUP BY YEAR(myDate), MONTH(myDate), DATENAME(MONTH, myDate)
)
SELECT [Year], [Month], [Month Name], [Total]
FROM MonthlySummary
ORDER BY [Year] ASC, [Month] ASC;

方案2:基于数据中的最新月份获取最近3个完整月份

如果需求是取数据中已存在的最新月份的前3个完整月(例如测试数据中最新月份为2025年2月,返回2025年2月、1月及2024年12月的数据),可使用以下代码:

WITH LatestMonth AS (
    SELECT
        -- 获取数据中最新月份的第一天
        DATEADD(MONTH, DATEDIFF(MONTH, 0, MAX(myDate)), 0) AS LatestMonthStart
    FROM myTable
    WHERE area = 'Shipping'
),
DateRange AS (
    SELECT
        -- 从最新月份往前推2个月,得到3个完整月的起始点
        DATEADD(MONTH, -2, LatestMonthStart) AS StartDate,
        -- 最新月份的下一个月第一天作为结束点
        DATEADD(MONTH, 1, LatestMonthStart) AS EndDate
    FROM LatestMonth
),
MonthlySummary AS (
    SELECT
        YEAR(myDate) AS [Year],
        MONTH(myDate) AS [Month],
        DATENAME(MONTH, myDate) AS [Month Name],
        SUM(Qty) AS [Total]
    FROM myTable
    CROSS JOIN DateRange
    WHERE area = 'Shipping'
      AND myDate >= StartDate
      AND myDate < EndDate
    GROUP BY YEAR(myDate), MONTH(myDate), DATENAME(MONTH, myDate)
)
SELECT [Year], [Month], [Month Name], [Total]
FROM MonthlySummary
ORDER BY [Year] ASC, [Month] ASC;

测试结果

使用方案2执行测试数据,将得到预期结果:

Year        Month       Month Name                     Total
2024        12          December                      9
2025        1           January                       4
2025        2           February                      2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:43:17