Mysql 在一个时间范围内分成5分钟的间隔
我在使用mySQL命令时遇到了一些困难Mysql 在一个时间范围内分成5分钟的间隔,mysql,sql,group-by,Mysql,Sql,Group By,我在使用mySQL命令时遇到了一些困难 SELECT a.timestamp, name, count(b.name) FROM time a, id b WHERE a.user = b.user AND a.id = b.id AND b.name = 'John' AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00' GROUP BY a.timestamp 这是我当前的输出语句
SELECT a.timestamp, name, count(b.name)
FROM time a, id b
WHERE a.user = b.user
AND a.id = b.id
AND b.name = 'John'
AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00'
GROUP BY a.timestamp
这是我当前的输出语句
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:32:22 John 2
2010-11-16 10:35:12 John 7
2010-11-16 10:36:34 John 1
2010-11-16 10:37:45 John 2
2010-11-16 10:48:26 John 8
2010-11-16 10:55:00 John 9
2010-11-16 10:58:08 John 2
如何将它们分组为5分钟间隔结果
我希望我的输出像
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:30:00 John 2
2010-11-16 10:35:00 John 10
2010-11-16 10:40:00 John 0
2010-11-16 10:45:00 John 8
2010-11-16 10:50:00 John 0
2010-11-16 10:55:00 John 11
您可能需要将时间戳分解为ymd:HM,并使用DIV 5将分钟划分为5分钟的存储箱—类似于
select year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 5,
name,
count(b.name)
FROM time a, id b
WHERE a.user = b.user AND a.id = b.id AND b.name = 'John'
AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00'
GROUP BY year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 12
…然后在客户端代码中对输出进行futz,使其以您喜欢的方式显示。或者,如果愿意,您可以使用sql concat运算符构建整个日期字符串,而不必获取单独的列
select concat(year(a.timestamp), "-", month(a.timestamp), "-" ,day(a.timestamp),
" " , lpad(hour(a.timestamp),2,'0'), ":",
lpad((minute(a.timestamp) DIV 5) * 5, 2, '0'))
…然后分组这适用于每个间隔 PostgreSQL 选择 带有时区“epoch”的时间戳+ 间隔“1秒”*round从时间戳中提取“历元”/300*300作为时间戳, 名称 姓名 从一开始 在哪里… 分组 从时间戳/300中提取'epoch',名称 MySQL 选择 时间戳-不确定 名称 姓名 从一开始 在哪里… 分组 UNIX\u时间戳DIV 300,名称
查询将类似于:
SELECT
DATE_FORMAT(
MIN(timestamp),
'%d/%m/%Y %H:%i:00'
) AS tmstamp,
name,
COUNT(id) AS cnt
FROM
table
GROUP BY ROUND(UNIX_TIMESTAMP(timestamp) / 300), name
我发现使用MySQL时,正确的查询可能是:
SELECT SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 ) AS ts_CEILING,
SUM(value)
FROM group_interval
GROUP BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 )
ORDER BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 ) DESC
让我知道你的想法。你应该使用GROUP BY UNIX\u TIMESTAMPtime\u stamp DIV 300而不是round。/300因为舍入,我发现一些记录被计算到两个分组结果集中 对于博士后,我发现使用
功能,如:
select name, sum(count), date_trunc('minute',timestamp) as timestamp
FROM table
WHERE xxx
GROUP BY name,date_trunc('minute',timestamp)
ORDER BY timestamp
您可以提供各种分辨率,如“分钟”、“小时”、“天”等。。。到目前为止,我遇到了同样的问题 我发现很容易按任何一分钟的间隔进行分组 只需将历元除以以秒为单位的分钟,然后取整或使用floor获得剩余的时间。所以,如果你想在5分钟内获得间歇时间,你需要300秒 这将按选定的分钟间隔正确返回数据组;但是,它不会返回不包含任何数据的间隔。为了获得这些空间隔,我们可以使用函数 结果:
interval_alias
-------------------
2010-11-16 10:30:00
2010-11-16 10:35:00
2010-11-16 10:40:00
2010-11-16 10:45:00
2010-11-16 10:50:00
2010-11-16 10:55:00
现在,为了得到间隔为零的结果,我们只需将两个结果集进行外部连接
最终结果将包括所有5分钟间隔的序列,甚至包括那些没有值的序列
interval count
------------------- ----
2010-11-16 10:30:00 2
2010-11-16 10:35:00 10
2010-11-16 10:40:00 0
2010-11-16 10:45:00 8
2010-11-16 10:50:00 0
2010-11-16 10:55:00 11
通过调整generate_系列的最后一个参数,可以轻松更改间隔。在我们的例子中,我们使用“5m”,但它可以是我们想要的任何间隔。这个如何:
select
from_unixtime(unix_timestamp(timestamp) - unix_timestamp(timestamp) mod 300) as ts,
sum(value)
from group_interval
group by ts
order by ts
;
不确定你是否还需要它
SELECT FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP(timestamp))/300)*300) AS t,timestamp,count(1) as c from users GROUP BY t ORDER BY t;
2016-10-29 19:35:00 | 2016-10-29 19:35:50 | 4 |
2016-10-29 19:40:00 | 2016-10-29 19:40:37 | 5 |
2016-10-29 19:45:00 | 2016-10-29 19:45:09 | 6 |
2016-10-29 19:50:00 | 2016-10-29 19:51:14 | 4|
2016-10-29 19:55:00 | 2016-10-29 19:56:17 | 1|
这将帮助你实现你的愿望 替换 dt-你的约会时间 c-调用字段 astro_transit1-您的桌子 300指5分钟,因此每次增加300表示时间间隔增加
SELECT FROM_UNIXTIME( 300 * ROUND( UNIX_TIMESTAMP( r.dt ) /300 ) ) AS 5datetime, (
SELECT r.c
FROM astro_transit1 ra
WHERE ra.dt = r.dt
ORDER BY ra.dt DESC
LIMIT 1
) AS first_val FROM astro_transit1 r GROUP BY UNIX_TIMESTAMP( r.dt )
DIV 300
LIMIT 0 , 30
六羟甲基三聚氰胺六甲醚。。。但是输出没有得到我想要得到的。它返回一列,我不太确定计数的值是多少…哦…没有得到mysql标志。。这是一个postgresql查询。。但基本上这应该可以通过mysql实现,toook。。而不是提取。。按轮分组UNIX_timestamp/300应执行以下操作trick@pHiL的评论在mySql上是正确的您应该使用DIV而不是round/否则间隔之间的界限是错误的只是在几个数据集上尝试了它,第二个查询在mySql上运行得很好,这是OPs关注的问题。既然@sky似乎缺席了,我们能不能在这个问题上达成共识?答案是什么?我也试过了。它每间隔2分钟或3分钟,再间隔5分钟显示第一条记录错误。注意:-我添加了一个条件来获取最近15分钟的记录。这一轮可能重复是正确的。/300在MySQL上做得不正确对于那些好奇的人来说,MySQL中的DIV是一个float分区的底层,它对bigint是安全的。我也尝试过这一点。它每间隔2分钟或3分钟,再间隔5分钟显示第一条记录错误。注意:-我添加了一个获取最近15分钟记录的条件。应该使用TRUNCATE或FLOOR而不是ROUND,因为舍入行为没有很好的定义,并且取决于使用的C库@tmarthal——不应该被高估。最初的问题是针对mysql的。您将5分钟间隔的5设置在哪里?对于以上内容,将Where子句更改为:Where timestamp>current_timestamp-interval“5分钟”。此查询似乎不执行所询问的操作,问题是“每隔5分钟”,而不是现在之前的5分钟。答案是:如果是MySQL的话,可能会是。似乎generate_series是一个PostgreSQL函数。太糟糕了。第一个查询只给出当前数据的结果,它统计两个时间段中两个时间段的中间记录
里奥兹。与两个时间段10:35和10:40一样,这两个时间段中的10:40都是10:35到10:40和10:40到10:45中的一个。请对您的查询进行解释。
interval count
------------------- ----
2010-11-16 10:30:00 2
2010-11-16 10:35:00 10
2010-11-16 10:40:00 0
2010-11-16 10:45:00 8
2010-11-16 10:50:00 0
2010-11-16 10:55:00 11
select
from_unixtime(unix_timestamp(timestamp) - unix_timestamp(timestamp) mod 300) as ts,
sum(value)
from group_interval
group by ts
order by ts
;
select
CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2)) AS '5MINDATE'
,count(something)
from TABLE
group by CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2))
SELECT FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP(timestamp))/300)*300) AS t,timestamp,count(1) as c from users GROUP BY t ORDER BY t;
SELECT FROM_UNIXTIME( 300 * ROUND( UNIX_TIMESTAMP( r.dt ) /300 ) ) AS 5datetime, (
SELECT r.c
FROM astro_transit1 ra
WHERE ra.dt = r.dt
ORDER BY ra.dt DESC
LIMIT 1
) AS first_val FROM astro_transit1 r GROUP BY UNIX_TIMESTAMP( r.dt )
DIV 300
LIMIT 0 , 30