MySQL查询按日期范围对结果进行分组?

时间:2013-09-20 20:32:29

标签: mysql sql subquery

我有一个系统,当他连接应用程序时,每隔2到5秒就会ping一次数据库。根据他的连接,ping时间范围可能更大,如10秒左右。

示例:

Pings: 1,4,6,8,9,12,16,20,50,180,187,189,200,203,206,210 ...

我想运行查询以获取ping之间不超过1分钟的范围,对它们进行分组,这样我就可以判断用户已连接多长时间,并保存到新表中,如:

Connections table:
user: X | start_date: 1   | end_date: 50  | duration: 49
user: X | start_date: 180 | end_date: 210 | duration: 30

由于ping,50,180,...超过1分钟,查询组不予考虑。

ping存储为时间戳,因此可以轻松转换为日期,从最后一次ping到第一次ping的范围将为我提供会话持续时间。

有没有在MySQL查询中执行此操作?有什么帮助吗?

编辑:添加ping历史记录架构

id  int(11)
user_id int(11)
ping_timestamp  int(11)

谢谢,

2 个答案:

答案 0 :(得分:6)

我将给定的示例数据加倍,以显示它如何与多个用户一起使用。 看到它在sqlfiddle here中正常工作。

select
userid, groupnum,
min(ping) as start_date,
max(ping) as end_date,
max(ping) - min(ping) as duration
from (
select
*,
@groupnum := if(@prevUser != userId, @groupnum + 1, @groupnum),
@groupnum := if(ping - @prevTS > 60, @groupnum + 1, @groupnum) as groupnum,
@prevUser := userid,
@prevTS := ping
from
Table1 t
, (select @groupnum:=1, @prevTS:=NULL, @prevUser:=NULL) vars
order by userid, ping
) sq
group by userid, groupnum

答案 1 :(得分:4)

尝试使用您的数据:

set @rnum = 1;
select user_id
     , min(ping_timestamp) start_date
     , max(ping_timestamp) end_date
     , max(ping_timestamp)-min(ping_timestamp) duration
  from ( select user_id
              , ping_timestamp
              , @rnum := if(ping_timestamp - @prev_ping_ts > 60, @rnum+1, @rnum) rnum
              , @prev_ping_ts := ping_timestamp
           from test2
          order by user_id, ping_timestamp
       ) t
 group by user_id, rnum
;