如何将数据库记录分组为15分钟的时间间隔

时间:2014-05-28 16:03:36

标签: mysql sql time-series aggregate-functions

我有一个表user_access,在MySQL数据库中有以下列:

id      int
user    int
access_time    datetime

我正在尝试运行一个查询,该查询给出user在给定的一组给定时间戳内以15分钟为间隔访问系统(access_time)的次数。

我目前的查询是:

select user, count(user) as users from user_access
where (access_time between '2013-05-28 02:00:00' and '2013-05-28 10:00:00')
group by user

我试图实现的结果如下:

Time                User       No of Times
--------------------------------------------------
8:00am - 8:15am     user1          20
8:00am - 8:15am     user2          5
8:15am - 8:30am     user1          15
8:15am - 8:30am     user2          23

3 个答案:

答案 0 :(得分:4)

首先,您的WHERE子句中有一个微妙的错误。你需要:

where access_time >= '2013-05-28 02:00:00' 
  and access_time < '2013-05-28 10:00:00'

因为您的四分之一小时范围从特定时间开始,直到之前另一个特定时间。在时间范围结束时,您需要<,而不是<=

然后,您需要一个表达式,该表达式可以采用任意DATETIME表达式并将其转换为发生它的四分之一小时开头的DATETIME

这样就可以了。

DATE_FORMAT(datestamp,'%Y-%m-%d %H:00:00') +
            INTERVAL (MINUTE(datestamp) -
                      MINUTE(datestamp) MOD 15) MINUTE

它将'2014-05-07 14:53:22'转换为'2014-05-07 14:45:00'

如果您愿意,可以将其定义为这样的存储函数:

DELIMITER $$
DROP FUNCTION IF EXISTS `TRUNC_15_MINUTES`$$
CREATE  FUNCTION `TRUNC_15_MINUTES`(datestamp DATETIME) 
                 RETURNS DATETIME
    NO SQL
    DETERMINISTIC
    RETURN DATE_FORMAT(datestamp,'%Y-%m-%d %H:00:00') +
                INTERVAL (MINUTE(datestamp) -
                          MINUTE(datestamp) MOD 15) MINUTE$$
DELIMITER ;

然后您可以像这样编写查询:

 select TRUNC_15_MINUTES(access_time) AS period_starting,
        user, count(user) as users 
   from user_access
 where access_time >= '2013-05-28 02:00:00' 
   and access_time <  '2013-05-28 10:00:00'
 group by TRUNC_15_MINUTES(access_time), user
 order by TRUNC_15_MINUTES(access_time), user

这是在这里写的。 http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

答案 1 :(得分:0)

您需要创建的公式是将每个access_time变为最接近的四分之一小时。

类似的东西:

CONCAT(Hour(access_time),":",floor(Minute(access_time)/15))*15)

然后,您可以将该公式放在select语句和group by语句中。您可以修改此伪代码语句以更改格式,添加每个季度的结束时间等。

答案 2 :(得分:0)

我会使用datediff和round来接近它。

采取任意日期并使用TIMESTAMPDIFF获取小数。将该日期舍入到15分钟,然后按其分组。

类似

select TIMESTAMPDIFF(MINUTE,randDate,access_time) DIV 15 as time, user, count(id) as users from user_access
    where (access_time > '2013-05-28 02:00:00' AND access_time < '2013-05-28 10:00:00')
    GROUP BY user, time

然后你要做的就是倒退以使它看起来很漂亮。使用时间将日期添加到randDate以返回到15分钟的间隔。

这非常粗糙,但它应该足以让你走上正确的轨道。