按月分组的Mysql查询

Posted

技术标签:

【中文标题】按月分组的Mysql查询【英文标题】:Mysql query for group by month 【发布时间】:2012-07-30 05:22:18 【问题描述】:

我想做一些事情,比如从表中获取所有行

where date >='2012-05-05' and date<='2012-07-20'

我希望 mysql 返回 "group by" rows mont wise 从

2012-05-05 to 2012-06-05(incerement 1 month)
2012-06-06 to 2012-07-06(increment 1` month)
and remaining 2012-07-07 to 2012-07-20 (group the remaining 14 days)

我怎样才能写出我的查询来达到同样的效果?

谢谢...

【问题讨论】:

这样您将返回 month-plus-one-day 行,而不仅仅是 month-wise。 【参考方案1】:

试试这个解决方案:

您可以通过TIMESTAMPDIFF() 函数GROUP BY 计算从参数最小值 (2012-05-05) + 1 到每行中的日期所经过的月数 TIMESTAMPDIFF() 函数:

GROUP BY TIMESTAMPDIFF(MONTH, '2012-05-05' + INTERVAL 1 DAY, date)

我们为您的最小参数+1天的原因是:

2012-05-052012-06-04 是 0 个月,但是... 2012-05-052012-06-05 是 1 个月

^ 因此,2012-06-05 上的行将与我们实际希望将其与它们分组时已过去 0 个月的日期分开分组。


编辑:我在摆弄这个解决方案,不仅按月间隔分组,还显示 from 每个间隔的日期。

检查一下:

SQLFiddle Demo

【讨论】:

我可以使用你上面的技术显示mysql正在分组的日期范围吗?\ @user1537158 看看我在 SQLFiddle 演示中做了什么。它看起来有点混乱和复杂,但它确实有效。只需将最小和最大参数分别插入 2012-05-052012-07-20 即可。另外,请确保在 GROUP BY 中包含 fromdatetodate 列,就像我在演示中所做的那样。 @user1537158 很高兴!实际上,我在尝试回答您的问题时才了解TIMESTAMPDIFF。现在我知道了一些我以前不知道的事情,所以感谢您提出这个问题!【参考方案2】:

您可以使用case expression,然后根据case 的结果进行分组。

SELECT 
  CASE 
    WHEN where date >='2012-05-05' and date<='2012-06-05' THEN 1 
    WHEN where date >='2012-06-06' and date<='2012-07-06' THEN 2 
    ELSE 3 
  END AS period, COUNT(*)
FROM your_table
GROUP BY period

【讨论】:

但是伙计,日期范围是动态选择的,而不是静态的,例如,我提到他们的日期可能是从 2012-01-24 到 2012-12-01 @user1537158 这只是一个例子,你应该自己定义你的范围。【参考方案3】:

希望对您有所帮助,我假设日期范围是这样动态的:

2012-01-01 to 2012-02-01
2012-02-02 to 2012-03-02
2012-03-03 to 2012-04-03
2012-04-04 to 2012-05-04
2012-05-05 to 2012-06-05
...

所以,我可以使用:

SELECT *, IF(day(date)>=month(date), month(date), month(date)-1) as PERIOD 
FROM your_tablename 
GROUP BY PERIOD;

【讨论】:

以上是关于按月分组的Mysql查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql 如何按月分组查询出当前年度每个月的短信数量(数据库中这个月要是为空的话就用0条怎么显示出来)

MySql按周,按月,按日分组统计数据

SQL按月统计,按日分组

mysql查询近半年每个月的总记录数

MySQL之按月拆分主表并按月分表写入数据提高数据查询速度

mysql计算行并按月分组[重复]