0

我从 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),它只能捕捉到“今天的出发”。午夜之后,它只捕获“新的一天出发”,而前一天的出发则丢失,因为它们有离开时间,例如“24:05”(=不大于 $time 00:05)。是否可以在第二天使用比 UNION 相同查询更轻的东西?如果 UNION 正在使用,我如何订购 LIMIT 修剪的离场?

Trips.start_time 和 end_time 是我用来加速 SQL 查询执行的辅助变量,它表示任意行程的 sequence1-arrival_time 和 MAXsequence-departure_time。

4

1 回答 1

0

使用UNION将每天的查询链接在一起将是您最好的选择,除非您可能想发出两个完全独立的查询,然后在您的应用程序中将结果合并在一起。用一个单一的语句(假设它甚至可能)完成所有这一切所需的扭曲是SELECT不值得的。

这里的部分复杂性在于活动服务 ID 的集合可能在连续几天之间变化,因此必须为每一天使用不同的集合。(有关如何使用子查询和表连接在 SQL 中构建此集合的建议,请参阅我对“如何使用日历异常来使用 GTFS 生成准确的时间表?”的回答。)

更多的复杂性源于必须以不同方式对待每一天的结果:为了正确排序结果集,我们需要从所有(且仅)昨天的时间中减去 24 小时。

尝试这样的查询,遵循您问题中的“伪 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
于 2014-07-28T00:08:29.943 回答