SQL 查询获取按月分组的最近 6 个月的数据?

SQL query for getting data for the last 6 months grouped by month?

我知道一个基本查询可以获取过去 6 个月的一些结果。让我们这样说:

SELECT * 
FROM RANDOM_TABLE
WHERE Date_Column >= DATEADD(MONTH, -6, GETDATE())

但是如果我想获得按月分组的结果 - 每个月回顾过去 6 个月怎么办? 理想情况下,结果的前三行如下所示(ID 的数量是随机的):

Month_and_year COUNT(ID)
January 2017 120
February 2017 160
March 2017 240

最后三行:

Month_and_year COUNT(ID)
November 2021 80
December 2021 350
January 2021 260

希望这是可以理解的。 提前致谢!

编辑: 在几个小时内,我做了一些更正。最值得注意的是,我更正了自连接查询以反映我的意图,还添加了更多详细信息以更好地解释正在发生的事情。

据我所知,有两种方法(它们在底层可能是相同的)。

另外,请注意这些解决方案假设您已经有一个月份字段。如果您有日期或时间戳字段,则应采取额外的准备步骤。

[附录] 更准确地说,我想说理想的情况是有一个 date/timestamp 字段,即 truncated/flattened 到每月的第一天。

举个例子,

month amount
2021-01-01 50
2021-02-01 20
2021-03-01 10
2021-04-01 100
2021-05-01 20
2021-06-01 40
2021-07-01 80
2021-08-01 50

第一种是使用“self-non-equi加入”

SELECT
    a.month,
    SUM(b.amount) AS amount_over_6_months
FROM table AS a
    INNER JOIN table AS b ON a.month BETWEEN b.month AND DATEADD(MONTH, 5, b.month)
WHERE a.month >= DATEADD(MONTH, -5, GETDATE())
GROUP BY a.month

这里发生的是你加入了 table 本身。具体来说,对于 (a) 别名中的每一行,您将连接来自 (b) 别名的六行。对于每一行,您将加入月份相同的行,一直追溯到五个月之前。所以...

a.month b.month a.amount b.amount
2021-01-01 2021-01-01 50 50
2021-02-01 2021-01-01 20 50
2021-02-01 2021-02-01 20 20
2021-03-01 2021-01-01 10 50
2021-03-01 2021-02-01 10 20
2021-03-01 2021-03-01 10 10
2021-04-01 2021-01-01 100 50
2021-04-01 2021-02-01 100 20
2021-04-01 2021-03-01 100 10
2021-04-01 2021-04-01 100 100
2021-05-01 2021-01-01 20 50
2021-05-01 2021-02-01 20 20
2021-05-01 2021-03-01 20 10
2021-05-01 2021-04-01 20 100
2021-05-01 2021-05-01 20 20
2021-06-01 2021-01-01 40 50
2021-06-01 2021-02-01 40 20
2021-06-01 2021-03-01 40 10
2021-06-01 2021-04-01 40 100
2021-06-01 2021-05-01 40 20
2021-06-01 2021-06-01 40 40
2021-07-01 2021-02-01 80 20
2021-07-01 2021-03-01 80 10
2021-07-01 2021-04-01 80 100
2021-07-01 2021-05-01 80 20
2021-07-01 2021-06-01 80 40
2021-07-01 2021-07-01 80 80
... ... ... ...

然后只需根据 (a) 别名中的月份进行分组,然后对来自 (b) 别名的金额求和即可。

这种方法的优点是它应该与供应商和代无关,保存 DATEADD() 函数。

第二种解决方案是使用 window 函数。我无法评论这是否适用于您的供应商和特定版本。

SELECT 
    month,
    SUM(amount) OVER (ORDER BY month ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)
FROM table