我有一张桌子可以存储事件中的GPS坐标(比如摇滚音乐会)。
看起来像这样:
sequence | event_id | location_id | device_number | timestamp | latitude | longitude | event
--------------------------------------------------------------------------------------------------------------------------------
1 | 101 | 2201 | 220 | 2013-10-29 05:01:00 | 37.757196 | -122.441681 | enter
2 | 101 | 2202 | 220 | 2013-10-29 05:02:00 | 37.757196 | -122.441681 | NULL
3 | 101 | 2203 | 220 | 2013-10-29 05:03:00 | 37.757196 | -122.441681 | NULL
4 | 101 | 2204 | 220 | 2013-10-29 05:04:00 | 37.757196 | -122.441681 | NULL
5 | 101 | 2205 | 220 | 2013-10-29 05:05:00 | 37.757196 | -122.441681 | NULL
6 | 101 | 2206 | 220 | 2013-10-29 05:06:00 | 37.757196 | -122.441681 | NULL
7 | 101 | 2207 | 220 | 2013-10-29 05:07:00 | 37.757196 | -122.441681 | exit
8 | 102 | 2208 | 220 | 2013-10-29 05:08:00 | 38.865221 | -123.920201 | enter
9 | 102 | 2209 | 220 | 2013-10-29 05:09:00 | 38.865221 | -123.920201 | NULL
10 | 102 | 2210 | 220 | 2013-10-29 05:10:00 | 38.865221 | -123.920201 | NULL
11 | 102 | 2211 | 220 | 2013-10-29 05:11:00 | 38.865221 | -123.920201 | NULL
12 | 102 | 2212 | 220 | 2013-10-29 05:12:00 | 38.865221 | -123.920201 | NULL
13 | 102 | 2213 | 220 | 2013-10-29 05:13:00 | 38.865221 | -123.920201 | NULL
14 | 102 | 2214 | 220 | 2013-10-29 05:14:00 | 38.865221 | -123.920201 | exit
15 | 101 | 2215 | 220 | 2013-10-29 05:15:00 | 37.757196 | -122.441681 | enter
16 | 101 | 2216 | 220 | 2013-10-29 05:16:00 | 37.757196 | -122.441681 | NULL
17 | 101 | 2217 | 220 | 2013-10-29 05:17:00 | 37.757196 | -122.441681 | NULL
18 | 101 | 2218 | 220 | 2013-10-29 05:18:00 | 37.757196 | -122.441681 | NULL
19 | 101 | 2219 | 220 | 2013-10-29 05:19:00 | 37.757196 | -122.441681 | NULL
20 | 101 | 2220 | 220 | 2013-10-29 05:20:00 | 37.757196 | -122.441681 | NULL
21 | 101 | 2221 | 220 | 2013-10-29 05:21:00 | 37.757196 | -122.441681 | exit
22 | 101 | 2222 | 330 | 2013-10-29 05:15:00 | 37.757197 | -122.441682 | enter
23 | 101 | 2223 | 330 | 2013-10-29 05:16:00 | 37.757197 | -122.441682 | NULL
24 | 101 | 2224 | 330 | 2013-10-29 05:17:00 | 37.757197 | -122.441682 | NULL
25 | 101 | 2225 | 330 | 2013-10-29 05:18:00 | 37.757197 | -122.441682 | NULL
26 | 101 | 2226 | 330 | 2013-10-29 05:19:00 | 37.757197 | -122.441682 | NULL
27 | 101 | 2227 | 330 | 2013-10-29 05:20:00 | 37.757197 | -122.441682 | exit
device_number
是用户拥有的特定GPS设备。event
列指示特定GPS device_number
何时根据其地理坐标走进或离开event_id。我想在名为billable_times
:
id | event_id | device_number | begin_time | end_time | duration (minutes)
----------------------------------------------------------------------------------------------
1 | 101 | 220 | 2013-10-29 05:01:00 | 2013-10-29 05:07:00 | 6
2 | 102 | 220 | 2013-10-29 05:08:00 | 2013-10-29 05:14:00 | 6
3 | 101 | 220 | 2013-10-29 05:15:00 | 2013-10-29 05:21:00 | 6
4 | 101 | 330 | 2013-10-29 05:15:00 | 2013-10-29 05:20:00 | 5
如何将一系列时间戳存储为仅包含begin_time
和end_time
的单行?
以下是一些有用的表创建脚本:
CREATE TABLE `intersections` (
`sequence` int(11) NOT NULL AUTO_INCREMENT,
`event_id` int(11) DEFAULT NULL,
`location_id` int(11) NOT NULL,
`device_number` varchar(255) NOT NULL,
`timestamp` datetime NOT NULL,
`latitude` decimal(20,15) NOT NULL,
`longitude` decimal(20,15) NOT NULL,
`event` varchar(255) DEFAULT NULL,
PRIMARY KEY (`sequence`),
UNIQUE KEY `index_intersections_on_location_id_and_event_id` (`location_id`,`event_id`)
);
INSERT INTO `intersections` (`sequence`, `event_id`, `location_id`, `device_number`, `timestamp`, `latitude`, `longitude`, `event`)
VALUES
(1, 101, 2201, '220', '2013-10-29 05:01:00', 37.757196, -122.441681, 'enter'),
(2, 101, 2202, '220', '2013-10-29 05:02:00', 37.757196, -122.441681, NULL),
(3, 101, 2203, '220', '2013-10-29 05:03:00', 37.757196, -122.441681, NULL),
(4, 101, 2204, '220', '2013-10-29 05:04:00', 37.757196, -122.441681, NULL),
(5, 101, 2205, '220', '2013-10-29 05:05:00', 37.757196, -122.441681, NULL),
(6, 101, 2206, '220', '2013-10-29 05:06:00', 37.757196, -122.441681, NULL),
(7, 101, 2207, '220', '2013-10-29 05:07:00', 37.757196, -122.441681, 'exit'),
(8, 102, 2208, '220', '2013-10-29 05:08:00', 37.757196, -122.441681, 'enter'),
(9, 102, 2209, '220', '2013-10-29 05:09:00', 37.757196, -122.441681, NULL),
(10, 102, 2210, '220', '2013-10-29 05:10:00', 37.757196, -122.441681, NULL),
(11, 102, 2211, '220', '2013-10-29 05:11:00', 37.757196, -122.441681, NULL),
(12, 102, 2212, '220', '2013-10-29 05:12:00', 37.757196, -122.441681, NULL),
(13, 102, 2213, '220', '2013-10-29 05:13:00', 37.757196, -122.441681, NULL),
(14, 102, 2214, '220', '2013-10-29 05:14:00', 37.757196, -122.441681, 'exit'),
(15, 101, 2215, '220', '2013-10-29 05:15:00', 37.757196, -122.441681, 'enter'),
(16, 101, 2216, '220', '2013-10-29 05:16:00', 37.757196, -122.441681, NULL),
(17, 101, 2217, '220', '2013-10-29 05:17:00', 37.757196, -122.441681, NULL),
(18, 101, 2218, '220', '2013-10-29 05:18:00', 37.757196, -122.441681, NULL),
(19, 101, 2219, '220', '2013-10-29 05:19:00', 37.757196, -122.441681, NULL),
(20, 101, 2220, '220', '2013-10-29 05:20:00', 37.757196, -122.441681, NULL),
(21, 101, 2221, '220', '2013-10-29 05:21:00', 37.757196, -122.441681, 'exit'),
(22, 101, 2222, '330', '2013-10-29 05:15:00', 37.757196, -122.441681, 'enter'),
(23, 101, 2223, '330', '2013-10-29 05:16:00', 37.757196, -122.441681, NULL),
(24, 101, 2224, '330', '2013-10-29 05:17:00', 37.757196, -122.441681, NULL),
(25, 101, 2225, '330', '2013-10-29 05:18:00', 37.757196, -122.441681, NULL),
(26, 101, 2226, '330', '2013-10-29 05:19:00', 37.757196, -122.441681, NULL),
(27, 101, 2227, '330', '2013-10-29 05:20:00', 37.757196, -122.441681, 'exit');
CREATE TABLE `billable_times` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event_id` int(11) DEFAULT NULL,
`device_number` varchar(255) DEFAULT NULL,
`begin_time` datetime DEFAULT NULL,
`end_time` datetime DEFAULT NULL,
`duration` float DEFAULT NULL,
PRIMARY KEY (`id`)
);
我正在使用MySQL,但任何SQL风格都会被接受。 (我会尝试将其翻译成MySQL :)。
答案 0 :(得分:1)
试试这个
insert into billable_times
SELECT event_id, device_number,
min(timestamp) begin,
max(timestamp) end,
sum(dura) duration from
(
SELECT sequence, event_id, device_number, timestamp,
if(@id <> concat(event_id,device_number), 0,
TIMESTAMPDIFF(MINUTE,@prev, timestamp)) dura,
@rank := if(@id <> concat(event_id,device_number), @rank + 1, @rank) rn,
@prev := timestamp, @id := concat(event_id,device_number)
from intersections, (Select @diff := 0, @id := null, @prev := null, @rank :=1) r
) v group by event_id, device_number, rn
order by rn;
select * from billable_times;