关于mysql:GROUP BY在不同年份连续几个月

GROUP BY continuous months in different years

我有一张桌子(但在很多地方):

1
2
3
4
5
6
7
8
9
DATE         STUFF
-------------------
2011-12-01   DATA
2011-12-02   DATA
2011-12-03   DATA
...
2011-12-31   DATA
2012-01-01   DATA
2012-01-02   DATA

我的表涵盖了从2005年到2012年的多年。我想获得每年每个月的AGGREGATE函数值,即SUM / AVG / MAX / MIN。 简单:

我希望在那些年里做同样的3个月时间......这适用于除了一个以外的所有人:

1
GROUP BY DATE_FORMAT(DATE, '%Y'), DATE_FORMAT(DATE, '%m') IN (12, 01, 02)

我的其他时间段有效,因为它们在同一年(03,04,05),(06,07,08)和(09,10,11)......但是上面的GROUP BY正在分组2012年12月 2012年1月/ 2月。我的时间段必须是2011年12月和2012年1月/ 2月,2010年12月和2011年1月/ 2月......

我希望保持这种通用性,因此我不必使用日期跨度进行更新,以便将代码放在多个位置的存储过程中。

如果在第12个月,那么我已经尝试将年份提前一年加入到表中。这产生了不良结果。


1
 GROUP BY floor((month(DATE) + year(DATE) * 12 -1 + %month_shift%) / %month_group_period%)

其中%month_group_period%在您的示例中为三(3)
和%month_shift%是一(1)个获得12月,1月,2月,等等

编辑:这也适用于5个月的时间(如果你想)


我在这里假设你真正想要用DATE_FORMAT(DATE, '%m') IN (12, 01, 02)做什么,但是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
SELECT IF(DATE_FORMAT(DATE, '%m') = 12, DATE_FORMAT(DATE, '%Y') + 1, DATE_FORMAT(DATE, '%Y')) AS yr,
    CASE DATE_FORMAT(DATE, '%m')
        WHEN 12 THEN 1
        WHEN 1 THEN 1
        WHEN 2 THEN 1
        WHEN 3 THEN 2
        WHEN 4 THEN 2
        WHEN 5 THEN 2
        WHEN 6 THEN 3
        WHEN 7 THEN 3
        WHEN 8 THEN 3
        WHEN 9 THEN 4
        WHEN 10 THEN 4
        WHEN 11 THEN 4
    END AS qtr
FROM ...
GROUP BY IF(DATE_FORMAT(DATE, '%m') = 12, DATE_FORMAT(DATE, '%Y') + 1, DATE_FORMAT(DATE, '%Y')),
    CASE DATE_FORMAT(DATE, '%m')
        WHEN 12 THEN 1
        WHEN 1 THEN 1
        WHEN 2 THEN 1
        WHEN 3 THEN 2
        WHEN 4 THEN 2
        WHEN 5 THEN 2
        WHEN 6 THEN 3
        WHEN 7 THEN 3
        WHEN 8 THEN 3
        WHEN 9 THEN 4
        WHEN 10 THEN 4
        WHEN 11 THEN 4
    END


我会尝试这样的事情:

1
2
GROUP BY DATE_FORMAT(IF(MONTH(`DATE`)=12,DATE_ADD(`DATE`,INTERVAL 1 YEAR),`DATE`),'%Y')
       , DATE_FORMAT(`DATE`,'%m')

基本上,如果月份是12,那么加1年。

实际上,我倾向于这样做:

1
2
3
4
5
6
GROUP BY DATE_FORMAT(DATE_ADD(`DATE`,INTERVAL IF(MONTH(`DATE`)=12,1,0) YEAR),'%Y')
       , CASE WHEN MONTH(`DATE`) IN (12,1,2) THEN 1
              WHEN MONTH(`DATE`) IN (3,4,5) THEN 2
              WHEN MONTH(`DATE`) IN (6,7,8) THEN 3
              WHEN MONTH(`DATE`) IN (9,10,11) THEN 4
          END

您需要从该组的日期减去一个月:

1
2
GROUP BY DATE_FORMAT(date_add(DATE,  interval 1 month), '%Y'),
         DATE_FORMAT(date_add(date, interval 1 month), '%m') IN (12, 01, 02)

您可能还需要修改选择。


我认为您不想使用GROUP BY来尝试这样做。您可能希望像这样编写查询

1
2
3
4
SELECT MONTH(date) as `month`, SUM(stuff) as `sum`
FROM table
WHERE YEAR(date) IN ('2010', '2011', 2012')
GROUP BY `month`

GROUP BY子句不是您应该过滤/格式化数据的位置。

当然,您可以使用您想要的任何聚合函数而不是SUM。您还可以省略所有年份的WHERE子句,或根据需要修改要包含的年份。

如果您想要年份和月份,您可以简单地修改查询,如下所示:

1
2
3
4
SELECT YEAR(date) as `year`, MONTH(date) as `month`, SUM(stuff) as `sum`
FROM table
WHERE `year` IN ('2010', '2011', 2012')
GROUP BY `year`, `month`