我试图解决以下问题,我有一个跟踪设备,每分钟都会更新其位置和在线状态。我试图通过将在线状态分组为select语句的几个小子集来将这些数据拆分为单独的旅程。
我知道我可以选择min&最大限度地将这些用于整个表格,但我不确定如何为其在线状态为真的每个组执行此操作。
虽然我可以在代码中实现所需的结果,但我需要将此操作移到服务器上,以满足电线性能的原因。
任何人都可以帮我指出正确的方向将其分解为sql语句吗?
[positions]
+-------------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| device_id | int unsigned | NO | | NULL | |
| lat | double | NO | | 0 | |
| lng | double | NO | | 0 | |
| date_time | datetime | NO | | NULL | |
| online | bit | NO | | 0 | |
+-------------------+-----------------------+------+-----+---------+----------------+
示例数据
id device_id lat lng date_time online
14 1 0.1 0.1 2014-07-11 05:21:37 0
17 1 0.11 0.11 2014-07-11 05:22:37 1
18 1 0.12 0.12 2014-07-11 05:23:37 1
24 1 0.13 0.13 2014-07-11 05:24:37 1
25 1 0.14 0.14 2014-07-11 05:25:37 1
26 1 0.14 0.14 2014-07-11 05:26:37 0
45 1 0.14 0.14 2014-07-11 05:27:37 0
47 1 0.14 0.14 2014-07-11 05:28:37 1
56 1 0.13 0.13 2014-07-11 05:29:37 1
67 1 0.12 0.12 2014-07-11 05:30:37 1
68 1 0.11 0.11 2014-07-11 05:31:37 1
78 1 0.11 0.11 2014-07-11 05:32:37 0
期望的结果
StartDateTime StartLat StartLng FinishDateTime FinishLat FinishLng
2014-07-11 05:22:37 0.11 0.11 2014-07-11 05:25:37 0.14 0.14
2014-07-11 05:28:37 0.14 0.14 2014-07-11 05:31:37 0.11 0.11
提前致谢, 史蒂夫
答案 0 :(得分:1)
您需要描述每个组的特征。最简单的方法是计算每行前online = 0
的数量:
select device_id, min(date_time) as StartDateTime, max(date_time) as FinishDateTime,
substring_index(group_concat(lat order by datetime asc), ',', 1) as StartLat,
substring_index(group_concat(long order by datetime asc), ',', 1) as StartLong,
substring_index(group_concat(lat order by datetime desc), ',', 1) as EndLat,
substring_index(group_concat(long order by datetime desc), ',', 1) as EndLong
from (select e.*,
(select count(*)
from example e2
where e2.device_id = e.device_id and
e2.date_time <= e.date_time and
e2.online = 0
) as grp
from example e
where e.online = 1
) e
group by device_id, grp;
这会使用substring_index()
/ group_concat()
技巧获取第一个和最后一个值。
select t.*,
efirst.lat as firstLat, efirst.long as firstLong,
ellast.lat as lastLat, elast.long as lastLong
from (select device_id, min(date_time) as StartDateTime, max(date_time) as FinishDateTime
from (select e.*,
(select count(*)
from example e2
where e2.device_id = e.device_id and
e2.date_time <= e.date_time and
e2.online = 0
) as grp
from example e
where e.online = 1
) e
group by device_id, grp
) t join
example efirst
on efirst.device_id = t.device_id and efirst.date_time = FirstDateTime join
example elast
on elast.device_id = t.device_id and elast.date_time = FinishDateTime;