我正在努力解决每隔一天在巴黎和柏林之间运行火车的问题。如果列车在T-2天没有运行,则被认为是“新的”,如果没有计划在T + 2天运行则被“结束”。这些列车的出发时间可以是(+/-)60分钟与参考列车(我们正在与之比较)。
因此,如果我有一个月的数据集,我必须计算每次旅行,如果它是新的或结束。数据格式为trip_id, start_city_id, end_city_id, dep_datetime
。
实施例
1,B,P,2018-04-01 07:50
2,B,P,2018-04-01 13:10
3,B,P,2018-04-01 15:40
4,B,P,2018-04-02 08:00
5,B,P,2018-04-02 12:50
6,B,P,2018-04-02 15:20
7,B,P,2018-04-03 09:50
8,B,P,2018-04-03 13:20
9,B,P,2018-04-03 15:40
10,B,P,2018-04-04 09:50
11,B,P,2018-04-04 13:20
12,B,P,2018-04-04 14:40
在上面的示例中=>
* train_id = 1可以被视为“已结束”,因为它没有安排在T + 2(4月3日)上运行,在(+/-)60分钟的时差与train_id = 1之间。
*虽然train_id = 2可以被认为是“无变化”,因为相应的列车在4月3日@ 12:50运行,这是在train_id = 2的出发时间的60分钟内
*虽然train_id = 7将被视为T-2(4月1日)的“新”列车,但没有相应的列车在(+/-)60分钟的出发时间内运行train_id = 7
我在数据库中有数据。 现在,我正在循环数据集中的每个项目,我不确定这是否是最好的方法
你认为我应该首先将所有必需的数据提取到我的程序(python)中并运行算法吗?或者我应该在数据库本身做一切,可能是MySQL中的存储过程?
我应该使用哪种算法和数据结构?
答案 0 :(得分:0)
你的方法是否足够快?称之为好。
类似下面的查询会给出答案(您需要将其调整为您的SQL方言)。它运作得足够快吗?然后称它为好。
select *,
not exists(select * from T T2
where T2.start_city_id=T.start_city_id
where T2.end_city_id=T.end_city_id
and T2.dep_datetime between T.dep_datetime - '49 hours'::interval and T.dep_datetime - '47 hours'::interval) as starting,
not exists(select * from T T2
where T2.start_city_id=T.start_city_id
where T2.end_city_id=T.end_city_id
and T2.dep_datetime between T.dep_datetime + '47 hours'::interval and T.dep_datetime + '49 hours'::interval) as ending
from T
如果没有,请尝试在(start_city_id,end_city_id,dep_datetime)上添加索引。作品?称之为好。
如果没有,请尝试优化查询。您应该进行顺序扫描和2次索引扫描。作品?称之为好。
如果所有其他方法都失败,则获取按(start_city_id,end_city_id,dep_datetime)排序的数据,然后获取匹配的上一个或下一个连接的每个记录二进制搜索(在python中)。有点棘手,但绝对应该足够快。