Mysql 在一个时间范围内分成5分钟的间隔

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 这是我当前的输出语句

我在使用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
这是我当前的输出语句

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