以前有人问过这个问题,但我面临的问题略有不同。
我有一个记录事件并存储它们的时间戳(作为日期时间)的表。我需要能够将时间分成几块并获取在该时间间隔内发生的事件数。间隔可以自定义(比如从 5 分钟到 1 小时甚至更长)。
显而易见的解决方案是将 datetime 转换为 unix_timestamp 将其除以间隔中的秒数,取其 floor 函数并将其乘以秒数。最后将 unix_timestamp 转换回日期时间格式。
这适用于小间隔。
select
from_unixtime(floor(unix_timestamp(event.timestamp)/300)*300) as start_time,
count(*) as total
from event
where timestamp>='2012-08-03 00:00:00'
group by start_time;
这给出了正确的输出
+---------------------+-------+
| start_time | total |
+---------------------+-------+
| 2012-08-03 00:00:00 | 11 |
| 2012-08-03 00:05:00 | 4 |
| 2012-08-03 00:10:00 | 4 |
| 2012-08-03 00:15:00 | 7 |
| 2012-08-03 00:20:00 | 8 |
| 2012-08-03 00:25:00 | 1 |
| 2012-08-03 00:30:00 | 1 |
| 2012-08-03 00:35:00 | 3 |
| 2012-08-03 00:40:00 | 3 |
| 2012-08-03 00:45:00 | 5 |
~~~~~OUTPUT SNIPPED~~~~~~~~~~~~
但是如果我将间隔增加到 1 小时(3600 秒)
mysql> select from_unixtime(floor(unix_timestamp(event.timestamp)/3600)*3600) as start_time, count(*) as total from event where timestamp>='2012-08-03 00:00:00' group by start_time;
+---------------------+-------+
| start_time | total |
+---------------------+-------+
| 2012-08-02 23:30:00 | 35 |
| 2012-08-03 00:30:00 | 30 |
| 2012-08-03 01:30:00 | 12 |
| 2012-08-03 02:30:00 | 18 |
| 2012-08-03 03:30:00 | 12 |
| 2012-08-03 04:30:00 | 4 |
| 2012-08-03 05:30:00 | 3 |
| 2012-08-03 06:30:00 | 13 |
| 2012-08-03 07:30:00 | 269 |
| 2012-08-03 08:30:00 | 681 |
| 2012-08-03 09:30:00 | 1523 |
| 2012-08-03 10:30:00 | 911 |
+---------------------+-------+
据我所知,未正确设置边界的原因是 unix_timestamp 会将时间从我的本地时区 (GMT + 0530) 转换为 UTC,然后输出数值。
所以像 2012-08-03 00:00:00 这样的值实际上是 2012-08-02 18:30:00。划分和使用 floor 会将分钟部分设置为 00。但是当我使用 from_unixtime 时,它会将其转换回 GMT + 0530,因此给我从 30 分钟开始的间隔。
无论时区如何,如何确保查询正常工作?我使用 MySQL 5.1.52,所以 to_seconds() 不可用
编辑: 无论时间间隔如何(可以是小时、分钟、天),查询也应该正确触发。一个通用的解决方案将不胜感激