如何从历史数据中检索行程?
How to retrieve trips from historical data?
我在 Hive 中有以下 table mytable
:
id radar_id car_id datetime
1 A21 123 2017-03-08 17:31:19.0
2 A21 555 2017-03-08 17:32:00.0
3 A21 777 2017-03-08 17:33:00.0
4 B15 123 2017-03-08 17:35:22.0
5 B15 555 2017-03-08 17:34:05.0
5 B15 777 2017-03-08 20:50:12.0
6 A21 123 2017-03-09 11:00:00.0
7 C11 123 2017-03-09 11:10:00.0
8 A21 123 2017-03-09 11:12:00.0
9 A21 555 2017-03-09 11:12:10.0
10 B15 123 2017-03-09 11:14:00.0
11 C11 555 2017-03-09 11:20:00.0
我想获取同一行程中通过雷达 A21
和 B15
的汽车的路线。例如,如果同一 car_id
的日期不同,则不是同一趟旅行。基本上,我想考虑同一辆车的雷达 A21
和 B15
之间的最大时间差应该是 30 分钟。如果它更大,那么行程就不一样了,例如 car_id
777
.
我的最终目标是统计每天的平均行程数(不唯一,所以如果同一辆车经过同一条路线2次,那么应该计算2次)。
预期结果如下:
radar_start radar_end avg_tripscount_per_day
A21 B15 1.5
日期 2017-03-08
雷达 A21
和 B15
之间有 2 次行程(由于 30 分钟的限制,汽车 777
不被考虑),而在date 2017-03-09
只有一趟。平均每天2+1=1.5次。
我怎样才能得到这个结果?基本上,我不知道如何在查询中引入 30 分钟限制以及如何按 radar_start
和 radar_end
.
对游乐设施进行分组
谢谢。
更新:
- 行程在开始日期登记。
- 如果汽车在
2017-03-08 23:55
时被雷达 A21
和在 2017-03-09 00:15
时被雷达 B15
触发,则应将其视为为日期 2017-03-08
.
- 如果
ids
6和8同车123
经过A21
两次,然后转向B15
(id
10).最后一骑id
8应该考虑。所以,8-10
。因此,最接近 B15
的前一个。解释是一辆汽车经过A21
两次,第二次转向B15
。
我没有注意到您正在使用 Hive
,因此开始为 SQL-Server
编写查询,但也许它会对您有所帮助。尝试这样的事情:
查询
select radar_start,
radar_end,
convert(decimal(6,3), count(*)) / convert(decimal(6,3), count(distinct dt)) as avg_tripscount_per_day
from (
select
t1.radar_id as radar_start,
t2.radar_id as radar_end,
convert(date, t1.[datetime]) dt,
row_number() over (partition by t1.radar_id, t1.car_id, convert(date, t1.[datetime]) order by t1.[datetime] desc) rn1,
row_number() over (partition by t2.radar_id, t2.car_id, convert(date, t2.[datetime]) order by t2.[datetime] desc) rn2
from trips as t1
join trips as t2 on t1.car_id = t2.car_id
and datediff(minute,t1.[datetime], t2.[datetime]) between 0 and 30
and t1.radar_id = 'A21'
and t2.radar_id = 'B15'
)x
where rn1 = 1 and rn2 = 1
group by radar_start, radar_end
输出
radar_start radar_end avg_tripscount_per_day
A21 B15 1.5000000000
示例数据
create table trips
(
id int,
radar_id char(3),
car_id int,
[datetime] datetime
)
insert into trips values
(1,'A21',123,'2017-03-08 17:31:19.0'),
(2,'A21',555,'2017-03-08 17:32:00.0'),
(3,'A21',777,'2017-03-08 17:33:00.0'),
(4,'B15',123,'2017-03-08 17:35:22.0'),
(5,'B15',555,'2017-03-08 17:34:05.0'),
(5,'B15',777,'2017-03-08 20:50:12.0'),
(6,'A21',123,'2017-03-09 11:00:00.0'),
(7,'C11',123,'2017-03-09 11:10:00.0'),
(8,'A21',123,'2017-03-09 11:12:00.0'),
(9,'A21',555,'2017-03-09 11:12:10.0'),
(8,'B15',123,'2017-03-09 11:14:00.0'),
(9,'C11',555,'2017-03-09 11:20:00.0')
select count(*) / count(distinct to_date(datetime)) as trips_per_day
from (select radar_id
,datetime
,lead(radar_id) over w as next_radar_id
,lead(datetime) over w as next_datetime
from mytable
where radar_id in ('A21','B15')
window w as
(
partition by car_id
order by datetime
)
) t
where radar_id = 'A21'
and next_radar_id = 'B15'
and datetime + interval '30' minutes >= next_datetime
;
+----------------+
| trips_per_day |
+----------------+
| 1.5 |
+----------------+
P.s.
如果您的版本不支持间隔,最后的代码记录可以替换为 -
and to_unix_timestamp(datetime) + 30*60 > to_unix_timestamp(next_datetime)
我在 Hive 中有以下 table mytable
:
id radar_id car_id datetime
1 A21 123 2017-03-08 17:31:19.0
2 A21 555 2017-03-08 17:32:00.0
3 A21 777 2017-03-08 17:33:00.0
4 B15 123 2017-03-08 17:35:22.0
5 B15 555 2017-03-08 17:34:05.0
5 B15 777 2017-03-08 20:50:12.0
6 A21 123 2017-03-09 11:00:00.0
7 C11 123 2017-03-09 11:10:00.0
8 A21 123 2017-03-09 11:12:00.0
9 A21 555 2017-03-09 11:12:10.0
10 B15 123 2017-03-09 11:14:00.0
11 C11 555 2017-03-09 11:20:00.0
我想获取同一行程中通过雷达 A21
和 B15
的汽车的路线。例如,如果同一 car_id
的日期不同,则不是同一趟旅行。基本上,我想考虑同一辆车的雷达 A21
和 B15
之间的最大时间差应该是 30 分钟。如果它更大,那么行程就不一样了,例如 car_id
777
.
我的最终目标是统计每天的平均行程数(不唯一,所以如果同一辆车经过同一条路线2次,那么应该计算2次)。
预期结果如下:
radar_start radar_end avg_tripscount_per_day
A21 B15 1.5
日期 2017-03-08
雷达 A21
和 B15
之间有 2 次行程(由于 30 分钟的限制,汽车 777
不被考虑),而在date 2017-03-09
只有一趟。平均每天2+1=1.5次。
我怎样才能得到这个结果?基本上,我不知道如何在查询中引入 30 分钟限制以及如何按 radar_start
和 radar_end
.
谢谢。
更新:
- 行程在开始日期登记。
- 如果汽车在
2017-03-08 23:55
时被雷达A21
和在2017-03-09 00:15
时被雷达B15
触发,则应将其视为为日期2017-03-08
. - 如果
ids
6和8同车123
经过A21
两次,然后转向B15
(id
10).最后一骑id
8应该考虑。所以,8-10
。因此,最接近B15
的前一个。解释是一辆汽车经过A21
两次,第二次转向B15
。
我没有注意到您正在使用 Hive
,因此开始为 SQL-Server
编写查询,但也许它会对您有所帮助。尝试这样的事情:
查询
select radar_start,
radar_end,
convert(decimal(6,3), count(*)) / convert(decimal(6,3), count(distinct dt)) as avg_tripscount_per_day
from (
select
t1.radar_id as radar_start,
t2.radar_id as radar_end,
convert(date, t1.[datetime]) dt,
row_number() over (partition by t1.radar_id, t1.car_id, convert(date, t1.[datetime]) order by t1.[datetime] desc) rn1,
row_number() over (partition by t2.radar_id, t2.car_id, convert(date, t2.[datetime]) order by t2.[datetime] desc) rn2
from trips as t1
join trips as t2 on t1.car_id = t2.car_id
and datediff(minute,t1.[datetime], t2.[datetime]) between 0 and 30
and t1.radar_id = 'A21'
and t2.radar_id = 'B15'
)x
where rn1 = 1 and rn2 = 1
group by radar_start, radar_end
输出
radar_start radar_end avg_tripscount_per_day
A21 B15 1.5000000000
示例数据
create table trips
(
id int,
radar_id char(3),
car_id int,
[datetime] datetime
)
insert into trips values
(1,'A21',123,'2017-03-08 17:31:19.0'),
(2,'A21',555,'2017-03-08 17:32:00.0'),
(3,'A21',777,'2017-03-08 17:33:00.0'),
(4,'B15',123,'2017-03-08 17:35:22.0'),
(5,'B15',555,'2017-03-08 17:34:05.0'),
(5,'B15',777,'2017-03-08 20:50:12.0'),
(6,'A21',123,'2017-03-09 11:00:00.0'),
(7,'C11',123,'2017-03-09 11:10:00.0'),
(8,'A21',123,'2017-03-09 11:12:00.0'),
(9,'A21',555,'2017-03-09 11:12:10.0'),
(8,'B15',123,'2017-03-09 11:14:00.0'),
(9,'C11',555,'2017-03-09 11:20:00.0')
select count(*) / count(distinct to_date(datetime)) as trips_per_day
from (select radar_id
,datetime
,lead(radar_id) over w as next_radar_id
,lead(datetime) over w as next_datetime
from mytable
where radar_id in ('A21','B15')
window w as
(
partition by car_id
order by datetime
)
) t
where radar_id = 'A21'
and next_radar_id = 'B15'
and datetime + interval '30' minutes >= next_datetime
;
+----------------+
| trips_per_day |
+----------------+
| 1.5 |
+----------------+
P.s.
如果您的版本不支持间隔,最后的代码记录可以替换为 -
and to_unix_timestamp(datetime) + 30*60 > to_unix_timestamp(next_datetime)