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之间的总和.
我在我的项目中尝试了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将与时间步长对齐.