Sql 如何从历史数据中检索行程?
我在Hive中有下表Sql 如何从历史数据中检索行程?,sql,hive,hiveql,Sql,Hive,Hiveql,我在Hive中有下表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-0
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
。例如,如果同一车辆id
的日期不同,则该行程不同。基本上,我要考虑的是,同一车辆的雷达<代码> A21和<代码> B15</代码>之间的最大时差应该是30分钟。如果更大,则行程不同,例如汽车id
777
我的最终目标是计算每天的平均出行次数(非唯一性,因此,如果同一辆车通过同一条路线2次,则应计算2次)
预期结果如下:
radar_start radar_end avg_tripscount_per_day
A21 B15 1.5
在日期2017-03-08
上,雷达A21
和B15
之间有2次行程(由于30分钟的限制,不考虑车辆777
),而在日期2017-03-09
上,只有1次行程。平均每天2+1=1.5次
我怎样才能得到这个结果?基本上,我不知道如何在查询中引入30分钟限制,以及如何按radar\u start
和radar\u end
对乘车进行分组
谢谢
更新:
ids
6和8的情况下,同一辆车123
经过A21
两次,然后转向B15
(id
10)。应考虑最后一次乘坐id为8的车辆。所以,8-10
。因此,最接近B15
的前一个。根据解释,一辆汽车经过A21
两次,第二次转向B15
李>
我没有注意到您正在使用Hive
,因此开始为SQLServer
编写查询,但它可能会对您有所帮助。试着这样做:
查询
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')
附加说明
如果您的版本不支持间隔,则最后的代码记录可以替换为-
和to\u unix\u timestamp(datetime)+30*60>to\u unix\u timestamp(next\u datetime)
@GordonLinoff:我在使用Hive。@草莓:你指的是哪种情况?以分钟为单位的最大差值应为30分钟,而不是更多。如果雷达A21
和B15
之间的间隔超过30分钟(或反之亦然),则这不是同一行程,不应计算在内。然后应该忽略它。@草莓:那么,这是同一次旅行,因为相差不到30分钟。即使他们在不同的日子?@草莓:不,如果这是不同的日子,那么这是不同的旅行。在这种情况下,我认为分钟的差值为20分钟加上24小时,所以超过30分钟。谢谢!我正在测试你的查询。一个问题:在我的例子中,datetime
是一个字符串。不幸的是,我无法控制DB。我只有阅读权。我应该使用到日期(datetime)
?您每天只计算一次每辆车。@Digoraius是的,看起来到日期(datetime)
是Hive中内置的功能。谢谢。我收到此错误失败:ParseException行21:18无法识别表达式规范“”中“interval”“30”“minutes”附近的输入。我想这就是问题所在。如何将其转换为datetime?(1)这是一个经过测试的代码(2)间隔是在两年多前的Hive 1.2.0(2015年5月18日)上引入的。(3) 如果您使用字符串而不是时间戳(为什么?),而不是使用CAST(4),则始终可以将时间戳转换为unixtimeThanks。我无法控制Db。我同意把datetime
作为字符串是很奇怪的。那么,我是否正确地理解了无论何时出现datetime
,我都应该用cast(datetime as date)
替换它?但在本例中,我将删除time part.cast(datetime作为时间戳)
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 |
+----------------+