8

当他连接应用程序时,我有一个系统每 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

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

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

无论如何要在 MySQL 查询中执行此操作吗?有什么帮助吗?

编辑:添加 ping 历史架构

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

谢谢,

4

2 回答 2

6

我将您给定的示例数据加倍以显示它如何与多个 userId 一起使用。

在这里看到它在 sqlfiddle 中工作。

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
于 2013-09-24T14:24:43.753 回答
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
;
于 2013-09-24T14:56:08.327 回答