我从GTFS开始,随着我的SQL查询出现了大问题:
SELECT *, ( some columns AS shortcuts )
FROM stop_times
LEFT JOIN trips ON stop_times.trip_id = trips.trip_id
WHERE trips.max_sequence != stop_times.stop_sequence
AND stop_id IN( $incodes )
AND trips.service_id IN ( $service_ids )
AND ( departure_time >= $time )
AND ( trips.end_time >= $time )
AND ( trips.start_time <= $time_plus_3hrs )
GROUP BY t,l,sm
ORDER BY t ASC, l DESC
LIMIT 14
这应该显示在接下来的3个小时内停止一些停止。 它可以工作,但接近午夜(例如23:50),它只能赶上&#34;今天的离开&#34;。午夜过后,它只能赶上新的一天离开&#34;和前一天的离开都不见了,因为他们有离开时间,例如&#34; 24:05&#34; (=不超过$ 00:05)。 第二天可以使用比UNION更轻的东西吗? 如果UNION正在使用,我如何通过LIMIT ORDER离场进行修剪?
Trips.start_time和end_time是我加速SQL查询执行的辅助变量,它意味着任何旅行的sequence1-arrival_time和MAXsequence-departure_time。
答案 0 :(得分:0)
使用UNION
将每天的查询链接在一起将是您最好的选择,除非您想要发出两个完全独立的查询,然后将结果合并到您的应用程序中。使用单SELECT
语句(假设它甚至可能)完成所有这些操作所需的扭曲不值得付出努力。
这里的部分复杂性是活动服务ID的集合可能在连续的几天之间变化,因此必须为每个服务ID使用不同的集合。 (有关如何使用子查询和表连接在SQL中构建此集的建议,请参阅my answer to "How do I use calendar exceptions to generate accurate schedules using GTFS?"。)
由于每天的结果必须区别对待,因此会产生更多的复杂性:要正确排序结果集,我们需要从昨天的所有时间(仅)中减去二十四小时。
尝试这样的查询,按照你的问题中的“伪SQL”并假设你正在使用MySQL / MariaDB:
SELECT *, SUBTIME(departure_time, '24:00:00') AS t, ...
FROM stop_times
LEFT JOIN trips ON stop_times.trip_id = trips.trip_id
WHERE trips.max_sequence != stop_times.stop_sequence
AND stop_id IN ( $incodes )
AND trips.service_id IN ( $yesterdays_service_ids )
AND ( departure_time >= ADDTIME($time, '24:00:00') )
AND ( trips.end_time >= ADDTIME($time, '24:00:00') )
AND ( trips.start_time <= ADDTIME($time_plus_3hrs, '24:00:00') )
UNION
SELECT *, departure_time AS t, ...
FROM stop_times
LEFT JOIN trips ON stop_times.trip_id = trips.trip_id
WHERE trips.max_sequence != stop_times.stop_sequence
AND stop_id IN ( $incodes )
AND trips.service_id IN ( $todays_service_ids )
AND ( departure_time >= $time )
AND ( trips.end_time >= $time )
AND ( trips.start_time <= $time_plus_3hrs )
GROUP BY t, l, sm
ORDER BY t ASC, l DESC
LIMIT 14