mysql中基于事件的报表

mysql中基于事件的报表,mysql,Mysql,我有下面的桌子 geofence time event vehicle g1 10:00 enter BMW g1 10:05 inside BMW g2 11:00 enter AUDI g2 11:06 inside AUDI g1 11:07 exit BMW g5 12:00 enter BMW g5 12:05 inside

我有下面的桌子

geofence  time   event    vehicle   
g1        10:00  enter    BMW
g1        10:05  inside   BMW
g2        11:00  enter    AUDI
g2        11:06  inside   AUDI
g1        11:07  exit     BMW
g5        12:00  enter    BMW
g5        12:05  inside   BMW
g5        12:10  inside   BMW
g5        13:00  exit     BMW
g1        15:00  enter    BMW
g1        15:05  inside   BMW
g1        16:00  exit     BMW
我需要报告一辆车在进入和离开地球围栏时,在地球围栏内停留了多长时间

vehicle  geofence enter  duration     exit
BMW      g1       10:00  1 hour 7min  11:07 
AUDI     g2       11:00  -            -
BMW      g5       12:00  1 hour       13:00
BMW      g1       15:00  1 hour       16:00 
编辑
车辆可以多次进出同一地理围栏,我们需要找出同一车辆当前进入事件的最近出口。车辆每10秒发出一次数据,有时我们需要报告一周的数据,如24*7*60*60/10数据

像这样的方法会奏效:

SELECT DISTINCT vehicle as car,
geofence as geo,
(select DISTINCT timeEvent from test where eventName = 'exit' and vehicle = car and geofence = geo) as exitTime, 
(select DISTINCT timeEvent from test where eventName = 'enter' and vehicle = car and geofence = geo) as enterTime, 
TIMEDIFF((select DISTINCT timeEvent from test where eventName = 'exit' and vehicle = car and geofence = geo), (select DISTINCT timeEvent from test where eventName = 'enter' and vehicle = car and geofence = geo)) as duration
FROM `test` WHERE vehicle = 'BMW' AND geofence = 'g1'
请注意,由于您使用了很多保留的单词,如退出和时间,所以我对名称做了一些更改。有关保留字的完整列表,请查看


另外,对于TIMEDIFF可能有一个更干净的解决方案,但它不允许我使用参考资料,类似这样的东西会起作用:

SELECT DISTINCT vehicle as car,
geofence as geo,
(select DISTINCT timeEvent from test where eventName = 'exit' and vehicle = car and geofence = geo) as exitTime, 
(select DISTINCT timeEvent from test where eventName = 'enter' and vehicle = car and geofence = geo) as enterTime, 
TIMEDIFF((select DISTINCT timeEvent from test where eventName = 'exit' and vehicle = car and geofence = geo), (select DISTINCT timeEvent from test where eventName = 'enter' and vehicle = car and geofence = geo)) as duration
FROM `test` WHERE vehicle = 'BMW' AND geofence = 'g1'
请注意,由于您使用了很多保留的单词,如退出和时间,所以我对名称做了一些更改。有关保留字的完整列表,请查看

另外,对于TIMEDIFF可能有一个更干净的解决方案,但它不允许我使用参考资料

以下是我的想法: 按土工围栏和车辆分组行 然后,为每个输入找到下一个出口,然后进行差异

select p1.vehicle,
  p1.geofence as geofence,
  p1.time as enter,
  ROUND(time_to_sec(TIMEDIFF (STR_TO_DATE(p2.time, "%H:%i"), STR_TO_DATE(p1.time, "%H:%i"))) /60) as duration,
  p2.time as _exit
  from (select * from vehicle_event WHERE event = "enter" GROUP BY geofence, vehicle) p1

  INNER JOIN

  (select * from vehicle_event WHERE event = "exit"  GROUP BY geofence, vehicle ORDER BY id LIMIT 1) p2
    on p1.vehicle = p2.vehicle AND p1.geofence = p2.geofence;
结果:

注意:持续时间以分钟表示,您可以将其更改为您想要的任何格式

测试数据:

CREATE TABLE IF NOT EXISTS vehicle_event (
  id bigint(20) NOT NULL AUTO_INCREMENT,
   geofence VARCHAR(30) NOT NULL,
  time VARCHAR(30) NOT NULL,
  event VARCHAR(30) NOT NULL,
  vehicle VARCHAR(30) NOT NULL,
  PRIMARY KEY (`id`));


  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g1", "10:00", "enter", "BMW");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "10:05", "inside", "BMW");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:00", "enter", "AUDI");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:06", "inside", "AUDI");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:07", "exit", "BMW");
更新:

如果车辆可以多次进入同一地理围栏,我们只需为每次进入找到下一个出口,并将分组标准放在连接后:

select p1.vehicle,
  p1.geofence as geofence,
  p1.time as enter,
  ROUND(time_to_sec(TIMEDIFF (STR_TO_DATE(p2.time, "%H:%i"), STR_TO_DATE(p1.time, "%H:%i"))) /60) as duration,
  p2.time as _exit
  from (select * from vehicle_event WHERE event = "enter") as p1

  INNER JOIN

  (select * from vehicle_event WHERE event = "exit"  ORDER BY id ) p2
    on p1.vehicle = p2.vehicle AND p1.geofence = p2.geofence AND p2.id > p1.id
  GROUP BY vehicle, geofence, enter;
使用的其他测试数据:

新结果: 以下是我的想法: 按土工围栏和车辆分组行 然后,为每个输入找到下一个出口,然后进行差异

select p1.vehicle,
  p1.geofence as geofence,
  p1.time as enter,
  ROUND(time_to_sec(TIMEDIFF (STR_TO_DATE(p2.time, "%H:%i"), STR_TO_DATE(p1.time, "%H:%i"))) /60) as duration,
  p2.time as _exit
  from (select * from vehicle_event WHERE event = "enter" GROUP BY geofence, vehicle) p1

  INNER JOIN

  (select * from vehicle_event WHERE event = "exit"  GROUP BY geofence, vehicle ORDER BY id LIMIT 1) p2
    on p1.vehicle = p2.vehicle AND p1.geofence = p2.geofence;
结果:

注意:持续时间以分钟表示,您可以将其更改为您想要的任何格式

测试数据:

CREATE TABLE IF NOT EXISTS vehicle_event (
  id bigint(20) NOT NULL AUTO_INCREMENT,
   geofence VARCHAR(30) NOT NULL,
  time VARCHAR(30) NOT NULL,
  event VARCHAR(30) NOT NULL,
  vehicle VARCHAR(30) NOT NULL,
  PRIMARY KEY (`id`));


  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g1", "10:00", "enter", "BMW");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "10:05", "inside", "BMW");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:00", "enter", "AUDI");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:06", "inside", "AUDI");
  insert into vehicle_event (geofence, time, event, vehicle) VALUES("g2", "11:07", "exit", "BMW");
更新:

如果车辆可以多次进入同一地理围栏,我们只需为每次进入找到下一个出口,并将分组标准放在连接后:

select p1.vehicle,
  p1.geofence as geofence,
  p1.time as enter,
  ROUND(time_to_sec(TIMEDIFF (STR_TO_DATE(p2.time, "%H:%i"), STR_TO_DATE(p1.time, "%H:%i"))) /60) as duration,
  p2.time as _exit
  from (select * from vehicle_event WHERE event = "enter") as p1

  INNER JOIN

  (select * from vehicle_event WHERE event = "exit"  ORDER BY id ) p2
    on p1.vehicle = p2.vehicle AND p1.geofence = p2.geofence AND p2.id > p1.id
  GROUP BY vehicle, geofence, enter;
使用的其他测试数据:

新结果:

谢谢你的想法,但有时同一辆车可以进入和退出同一个地理围栏超过2-3次,在这种情况下,我们需要找到最近的地理围栏退出时间,如果数据集太大,查询将减慢。抱歉,没有看到你的评论;是周末,;请检查更新是否有助于了解您的想法,但有时同一车辆可以进入和退出同一地理围栏超过2-3次,在这种情况下,我们需要找到最近的地理围栏退出时间,如果数据集太大,查询将减慢。抱歉,没有看到您的评论;是周末,;请检查更新是否有帮助