按“每30天”分组mysql结果

时间:2014-05-08 15:10:15

标签: mysql group-by

我有一个问题:

SELECT 
  COUNT(id) as amount,
  DATEDIFF(expire, buydate) as days
FROM `vw8mv_orders`
GROUP BY MONTH(expire)

结果是:

    amount  days
    1       22
    1       30
    1       105
    1       161

我想在一组(每30天)看到这些结果。如果天数值在1到30天之间,则将其放入30天组,如果下注31-60,则放入60天组等。

例如:

    amount  time
      2     30 days
      0     60 days
      1     90 days

2 个答案:

答案 0 :(得分:4)

您需要创建一个计算列以进行分组。有几种方法可用于计算,但一个好的选择可能是使用DIV operator的整数除法:

SELECT
    COUNT(id) as amount,
    (((datediff(expire, buydate) DIV 30) + 1) * 30) as timegroup
FROM
    table
GROUP BY timegroup;

我喜欢这种方法而不是使用例如some fancy arithmetic with ROUND()的原因是,它更清楚你要做的是什么。 datediff(expire, buydate) DIV 30说,取决于这些日期的不同,并告诉我"多少30多岁"在这个数字。

您分组所需的一切;剩下的就是让列以你想要的方式显示,30, 60, 90, ...而不是0, 1, 2, ...

如果您对整数除法不满意,另一种选择是CEILING function

SELECT
    COUNT(id) as amount,
    30 * CEILING(datediff(expire, buydate) / 30) as timegroup
FROM
    table
GROUP BY timegroup;

从数学角度讲,CEILING(x / N)相当于((x DIV N) + 1),但它对CEILING()的忙碌程度稍低。

答案 1 :(得分:1)

您可以对查询返回的结果进行子选择,下面是示例查询

SELECT COUNT(`amount`) as amount,
 CONCAT(ROUND(`days` / 30) * 30, ' Days')
 as `time`
 FROM `t`
 GROUP BY `time`
ORDER BY ROUND(`days` / 30)

Demo

对于您的查询,您可以这样做

SELECT COUNT(`amount`) as amount,
 CONCAT(ROUND(`days` / 30) * 30, ' Days')
 as `time`
FROM(
SELECT COUNT(id) as amount,
 datediff(expire, buydate) as days 
FROM `vw8mv_orders` 
GROUP BY MONTH(expire)
) t
 GROUP BY `time`
ORDER BY ROUND(`days` / 30)