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) に近づくと、「今日の出発」のみをキャッチします。真夜中以降は「新しい日の出発」のみをキャッチし、前日からの出発は欠落しています。これは、departure_time が「24:05」(= $time 00:05 より大きくない)であるためです。翌日にUNIONの同じクエリよりも軽いものを使用することは可能ですか? UNION を使用している場合、LIMIT によるトリミングの出発を注文するにはどうすればよいですか?

Trips.start_time と end_time は、SQL クエリの実行を高速化するための補助変数です。これは、任意の旅行の sequence1-arrival_time と MAXsequence-departure_time を意味します。

4

1 に答える 1

0

UNION2 つの完全に別個のクエリを発行し、アプリケーションで結果をマージする場合を除き、毎日のクエリをリンクするために使用するのが最善の策です。単一のステートメントでこれらすべてを実行するために必要なゆがみ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 に答える