【问题标题】:How to group datebase records into 15-minute time intervals如何将数据库记录分组为 15 分钟的时间间隔
【发布时间】:2014-07-17 23:17:58
【问题描述】:

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

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

【问题讨论】:

  • 如果用户在指定时间段内没有访问权限,您希望发生什么?
  • @GordonLinoff 不错。我从来没想过这点。没有用户记录时为零。
  • 您发布的“结果”是预期结果,还是当前结果?
  • @GigaWatt 结果是预期的结果格式。我还没有完全开发出查询。

标签: mysql sql time-series aggregate-functions


【解决方案1】:

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

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

因为您的一刻钟范围是从一个特定时间到另一个特定时间之前的那一刻。在您的时间范围结束时,您需要 &lt;,而不是 &lt;=

然后,您需要一个可以采用任意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/

【讨论】:

  • 很好的回应。我还在测试。如果在特定的 15 分钟间隔内没有返回结果,我如何将 users 默认为 0
  • 包含零行应该是另一个问题的主题(除非@GordonLinoff 知道一些非常巧妙的技巧)。
  • 我目前正在测试查询,完成后我会回复您。感谢您的努力。
  • 关于如何将查询中具有间隔值和默认 users 的行包含为 0 的任何想法
  • 就像我说的,这是一个不同的问题。但这里有一些想法的指针。 plumislandmedia.net/mysql/…
【解决方案2】:

我会使用 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 分钟间隔。

这很粗略,但它应该足以让你走上正确的轨道。

【讨论】:

    【解决方案3】:

    您需要创建一个公式,将每个 access_time 转换为最接近的一刻钟。

    类似:

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

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

    【讨论】:

    • 这是 MySQL。你需要CONCAT(),而不是&amp;
    • 对不起。伪代码。添加了 Concat()。重点是将各个瞬间动态转换为一刻钟
    猜你喜欢
    • 2012-11-18
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多