SELECT/GROUP BY - 时间段(10秒,30秒等)

Eri*_*son 39 mysql sql select group-by

我有一个表(MySQL),每隔n秒捕获一次样本.该表有许多列,但重要的是两个:时间戳(TIMESTAMP类型)和计数(INT类型).

我想做的是在一定范围内获得计数列的总和和平均值.例如,我每2秒记录一次样本,但我希望所有样本的10秒或30秒窗口中所有样本的计数列总和.

这是一个数据示例:

+---------------------+-----------------+
| time_stamp          | count           |
+---------------------+-----------------+
| 2010-06-15 23:35:28 |               1 |
| 2010-06-15 23:35:30 |               1 |
| 2010-06-15 23:35:30 |               1 |
| 2010-06-15 23:35:30 |             942 |
| 2010-06-15 23:35:30 |             180 |
| 2010-06-15 23:35:30 |               4 |
| 2010-06-15 23:35:30 |              52 |
| 2010-06-15 23:35:30 |              12 |
| 2010-06-15 23:35:30 |               1 |
| 2010-06-15 23:35:30 |               1 |
| 2010-06-15 23:35:33 |            1468 |
| 2010-06-15 23:35:33 |             247 |
| 2010-06-15 23:35:33 |               1 |
| 2010-06-15 23:35:33 |              81 |
| 2010-06-15 23:35:33 |              16 |
| 2010-06-15 23:35:35 |            1828 |
| 2010-06-15 23:35:35 |             214 |
| 2010-06-15 23:35:35 |              75 |
| 2010-06-15 23:35:35 |               8 |
| 2010-06-15 23:35:37 |            1799 |
| 2010-06-15 23:35:37 |              24 |
| 2010-06-15 23:35:37 |              11 |
| 2010-06-15 23:35:37 |               2 |
| 2010-06-15 23:35:40 |             575 |
| 2010-06-15 23:35:40 |               1 |
| 2010-06-17 10:39:35 |               2 |
| 2010-06-17 10:39:35 |               2 |
| 2010-06-17 10:39:35 |               1 |
| 2010-06-17 10:39:35 |               2 |
| 2010-06-17 10:39:35 |               1 |
| 2010-06-17 10:39:40 |              35 |
| 2010-06-17 10:39:40 |              19 |
| 2010-06-17 10:39:40 |              37 |
| 2010-06-17 10:39:42 |              64 |
| 2010-06-17 10:39:42 |               3 |
| 2010-06-17 10:39:42 |              31 |
| 2010-06-17 10:39:42 |               7 |
| 2010-06-17 10:39:42 |             246 |
+---------------------+-----------------+

我想要的输出(基于上面的数据)应如下所示:

+---------------------+-----------------+
| 2010-06-15 23:35:00 |               1 |  # This is the sum for the 00 - 30 seconds range
| 2010-06-15 23:35:30 |            7544 |  # This is the sum for the 30 - 60 seconds range
| 2010-06-17 10:39:35 |             450 |  # This is the sum for the 30 - 60 seconds range
+---------------------+-----------------+

我已经使用GROUP BY来收集这些数字的第二个或者每分钟,但是我似乎无法弄清楚语法来获得子分钟或范围的GROUP BY命令才能正常工作.

我将主要使用此查询将此表中的数据虹吸到另一个表.

谢谢!

Ham*_*ite 67

GROUP BY UNIX_TIMESTAMP(time_stamp) DIV 30

或者说出于某种原因你想要以20秒的间隔对它们进行分组,这将是DIV 20等等.改变GROUP BY你可以使用的值之间的界限

GROUP BY (UNIX_TIMESTAMP(time_stamp) + r) DIV 30

where r是一个小于30的文字非负整数.所以

GROUP BY (UNIX_TIMESTAMP(time_stamp) + 5) DIV 30

应该给你hh:mm:05和hh:mm:35之间以及hh:mm:35和hh:mm + 1:05之间的总和.


mac*_*13k 6

我在我的项目中尝试了Hammerite的解决方案,但是在系列中缺少样本的情况下,它没有奏效.以下是应该从metric_table中选择时间戳(ts),用户名和平均度量的查询示例,并按27分钟的时间间隔对结果进行分组:

select 
    min(ts), 
    user_name, 
    sum(measure) / 27
from metric_table 
where 
    ts between date_sub('2015-03-17 00:00:00', INTERVAL 2160 MINUTE) and '2015-03-17 00:00:00' 

group by unix_timestamp(ts) div 1620, user_name 
order by ts, user_name
;
Run Code Online (Sandbox Code Playgroud)

注意:27分钟(在选择中)= 1620秒(在分组中),2160分钟= 3天(这是时间范围)

当我针对不规则记录样本的时间序列运行此查询时(换句话说:对于任何给定的时间戳,无法保证找到所有用户名的度量值),结果没有根据间隔标记(未放置每27分钟一次).我怀疑这是由于min(ts)在某些组中返回一个大于预期楼层(ts0 + i*interval)的时间戳.我将以前的查询修改为这个:

select 
    from_unixtime(unix_timestamp(ts) - unix_timestamp(ts) mod 1620) as ts1, 
    user_name, 
    sum(measure) / 27
from metric_table
where 
    ts between date_sub('2015-03-17 00:00:00', INTERVAL 2160 MINUTE) and '2015-03-17 00:00:00' 

group by ts1, user_name 
order by ts1, user_name
;
Run Code Online (Sandbox Code Playgroud)

即使样品丢失也能正常工作.我认为这是因为一旦数学移动到选择它,它保证ts1将与时间步长对齐.