mysql:在事件日志中查找开始时间 - 按会话时间分组

时间:2017-09-22 08:59:09

标签: mysql group-by

我有一个事件日志 - 例如网络访问日志。

Id   Date                 IP
---------------------------------
100; 2017-09-21 08:00:00; 192.168.1.10
101; 2017-09-21 08:10:00; 192.168.1.100
102; 2017-09-21 08:15:00; 192.168.1.100
103; 2017-09-21 08:19:00; 192.168.1.10
104; 2017-09-21 08:30:00; 192.168.1.100
105; 2017-09-21 08:45:00; 192.168.1.10
106; 2017-09-21 09:10:00; 192.168.1.100
107; 2017-09-21 09:11:00; 192.168.1.100
108; 2017-09-21 09:30:00; 192.168.1.10
109; 2017-09-21 09:40:00; 192.168.1.10

我想获得某个会话超时内的开始和结束时间列表。所以,让我们说会话超时是20分钟。来自同一IP的所有事件应在20分钟内分组到一个结果集中,最小(数据),最大(日期)。

DateFrom             DateTo               IP
-----------------------------------------------------------------
2017-09-21 08:00:00; 2017-09-21 08:39:00; 192.168.1.10
2017-09-21 08:45:00; 2017-09-21 09:05:00; 192.168.1.10
2017-09-21 09:30:00; 2017-09-21 10:00:00; 192.168.1.10
2017-09-21 08:10:00; 2017-09-21 08:50:00; 192.168.1.100
2017-09-21 09:10:00; 2017-09-21 09:31:00; 192.168.1.100

注意第二列:08:39不在日志中 - 但它是08:19 + 20分钟超时,因为在会话超时内没有成功的事件。

我找到了一些帮助我的SO答案,但我总是因为加入max和min date列而失败。 MySQL GROUP BY DateTime +/- 3 seconds

1 个答案:

答案 0 :(得分:2)

尝试使用变量,不确定它是否适合您数据中的所有场合,但您可以查看:

select min(`date`) datefrom, max(`date`) + interval 20 minute dateto ,ip
from (
  select
      log.*,
      @newgrp := case when (@grp = ip and (`date` - interval 20 minute) < @date) then @newgrp else @newgrp + 1 end newgrp,
      @grp := ip, @date := `date`
  from log
  cross join (
      select @grp := null, @date := null, @newgrp := 0
  ) t
  order by ip, `date`
) t
group by newgrp, ip

请在此处查看 SQLFiddle Demo