0

休日のバス移動時間を含む SQL テーブルがあります。この表は往路と復路を組み合わせたもので (オプション 0 は往路、オプション 1 は復路)、ユーザーに複数の選択肢を提供します (オプション 2 は、往路 3 回と復路 2 回のオプションをカウントします)。表には停車地間のすべてがリストされているため、各ルートは複数の行にまたがる場合があります。

  • 行きます:

    • オプション 0: ロンドン -> アムステルダム -> ベルリン
    • オプション 1: ロンドン -> チューリッヒ -> ベルリン
    • オプション 2: ロンドン -> パリ -> ローマ -> ベルリン
  • 戻る

    • オプション 0: ベルリン -> アムステルダム -> ロンドン
    • オプション 1: ベルリン -> チューリッヒ -> ロンドン

[オプション] 列には、旅行が行きか帰りかが表示されます。Option2 列は、オプションをまとめて一致させます。Option3 列は、各オプションの正しい順序を示しています。

+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| ID | DepartureDateTime   | ArrivalDateTime     | Departure        | Arrival        | Option       | Option2       | Option3       |
+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| 72 | 2013-10-01 13:45:00 | 2013-10-02 16:40:00 | London           | Amsterdam      |            0 |             0 |             0 |
| 73 | 2013-10-02 17:35:00 | 2013-10-03 19:05:00 | Amsterdam        | Berlin         |            0 |             0 |             1 |
| 74 | 2013-10-01 17:00:00 | 2013-10-02 19:50:00 | London           | Zurich         |            0 |             1 |             0 |
| 75 | 2013-10-02 21:10:00 | 2013-10-03 22:40:00 | Zurich           | Berlin         |            0 |             1 |             1 |
| 76 | 2013-10-01 06:00:00 | 2013-10-02 08:40:00 | London           | Paris          |            0 |             2 |             0 |
| 77 | 2013-10-02 12:30:00 | 2013-10-03 14:05:00 | Paris            | Rome           |            0 |             2 |             1 |
| 78 | 2013-10-03 12:30:00 | 2013-10-04 14:05:00 | Rome             | Berlin         |            0 |             2 |             2 |
| 79 | 2013-10-10 14:50:00 | 2013-10-11 16:30:00 | Berlin           | Amsterdam      |            1 |             0 |             0 |
| 80 | 2013-10-11 17:05:00 | 2013-10-12 17:50:00 | Amsterdam        | London         |            1 |             0 |             1 |
| 81 | 2013-10-10 06:45:00 | 2013-10-11 08:25:00 | Berlin           | Zurich         |            1 |             1 |             0 |
| 82 | 2013-10-11 15:20:00 | 2013-10-12 16:05:00 | Zurich           | London         |            1 |             1 |             1 |
+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+

2 つの異なるクエリが必要です。

1) 次の 2 点に基づいてテーブルを並べ替えます。出発の場合: 旅行の最初の出発 (ロンドンを出発)。b. 帰りの場合: 最後の帰りの旅 (ロンドンに行く) の到着。

2) 特定の日付/時間範囲に一致する旅行のみを返します: 最初の出発 (ロンドンから出発) と最終的な帰り (ロンドンに到着)。たとえば、朝の出発と夕方の到着がある旅行を表示します。

詳細が必要な場合、または何か見逃している場合はお知らせください。

よろしくお願いいたします。

編集 1

私の投稿全体を読んでください。ここで重要なことは、行が互いに関連していることです。たとえば、以下の 2 つの行は「一緒」でなければなりません。私が扱っているアプリケーションは、正しい順序によって異なります。

+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| ID | DepartureDateTime   | ArrivalDateTime     | Departure        | Arrival        | Option       | Option2       | Option3       |
+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| 72 | 2013-10-01 13:45:00 | 2013-10-02 16:40:00 | London           | Amsterdam      |            0 |             0 |             0 |
| 73 | 2013-10-02 17:35:00 | 2013-10-03 19:05:00 | Amsterdam        | Berlin         |            0 |             0 |             1 |

つまり、行が混同されるため、出発日でソートすることはできません。

したがって、出発に基づいて上記の旅行を並べ替えたい場合、朝 6 時に出発するため、ロンドンからパリを経由してベルリンへの旅行が最初に表示されます。

+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| ID | DepartureDateTime   | ArrivalDateTime     | Departure        | Arrival        | Option       | Option2       | Option3       |
+----+---------------------+---------------------+------------------+----------------+--------------+---------------+---------------+
| 76 | 2013-10-01 06:00:00 | 2013-10-02 08:40:00 | London           | Paris          |            0 |             2 |             0 |
| 77 | 2013-10-02 12:30:00 | 2013-10-03 14:05:00 | Paris            | Rome           |            0 |             2 |             1 |
| 78 | 2013-10-03 12:30:00 | 2013-10-04 14:05:00 | Rome             | Berlin         |            0 |             2 |             2 |
| 72 | 2013-10-01 13:45:00 | 2013-10-02 16:40:00 | London           | Amsterdam      |            0 |             0 |             0 |
| 73 | 2013-10-02 17:35:00 | 2013-10-03 19:05:00 | Amsterdam        | Berlin         |            0 |             0 |             1 |

上記の部分的な表は、ソートされた結果がどのようになるかを示しています。基本的に、並べ替えアルゴリズムは、最初の出発の行を考慮し、並べ替えの他の行を無視する必要がありますが、最終結果には、最初の旅行の「下」にある旅行の関連する停車地が含まれている必要があります。

それは恐ろしいことですか、それとも何ですか?

どんな助けでも大歓迎です。

編集 2

リクエストに応じて、MySQL 5.1 を使用しています。

編集 3

メンバー @fancyPants が最初のクエリを解決しました。Option=0 から Option=1 への変更を考慮して、少し変更を加えました。

SELECT 
`ID`, `DepartureDateTime`, `ArrivalDateTime`, `Departure`, `Arrival`, `Option`, `Option2`, `Option3`
FROM (
SELECT 
t.*,
CASE WHEN Option != @prev OR Option2 != @prev2 THEN @min_date := DepartureDateTime ELSE @min_date END as min_date,
CASE WHEN Option2 = @prev2 THEN @counter := @counter + 1 ELSE @counter := 0 END as counter,
@prev := Option, @prev2 := Option2
FROM Table1 t 
, (SELECT @min_date:=(SELECT DepartureDateTime FROM Table1 ORDER BY `Option`, Option2, Option3 LIMIT 1), @counter:=0, @prev:=NULL, @prev2:=NULL) vars
order by `Option`, Option2, Option3
) sq
ORDER BY min_date, counter

ファンシーパンツ、素晴らしい作品をありがとう!

残念ながら、2 番目のクエリについては十分に明確ではありませんでした。私が必要とするのは、最初のクエリの上に構築することです (したがって、結果はソートされます)。次に、日時の範囲に基づいて結果を制限します。

4

2 に答える 2

2

これはそれほど簡単ではありません。これが私が思いついたものです(MySQLを想定):

次の 2 点に基づいてテーブルを並べ替えます。出発の場合: 旅行の最初の出発 (ロンドンから出発)。

SELECT 
`ID`, `DepartureDateTime`, `ArrivalDateTime`, `Departure`, `Arrival`, `Option`, `Option2`, `Option3`
FROM (
SELECT 
t.*,
CASE WHEN Option2 != @prev THEN @min_date := DepartureDateTime ELSE @min_date END as min_date,
CASE WHEN Option2 = @prev THEN @counter := @counter + 1 ELSE @counter := 0 END as counter,
@prev := Option2
FROM Table1 t 
, (SELECT @min_date:=(SELECT DepartureDateTime FROM Table1 ORDER BY `Option`, Option2, Option3 LIMIT 1), @counter:=0, @prev:=NULL) vars
order by `Option`, Option2, Option3
) sq
ORDER BY min_date, counter

返品する場合:

SELECT 
`ID`, `DepartureDateTime`, `ArrivalDateTime`, `Departure`, `Arrival`, `Option`, `Option2`, `Option3`
FROM (
SELECT 
t.*,
CASE WHEN Option2 != @prev THEN @min_date := ArrivalDateTime ELSE @min_date END as min_date,
CASE WHEN Option2 = @prev THEN @counter := @counter + 1 ELSE @counter := 0 END as counter,
@prev := Option2
FROM Table1 t 
, (SELECT @min_date:=(SELECT ArrivalDateTime FROM Table1 ORDER BY `Option`, Option2, Option3 LIMIT 1), @counter:=0, @prev:=NULL) vars
order by `Option`, Option2, Option3
) sq
ORDER BY min_date, counter

あなたの2番目の質問について、私がそれが正しいと理解した場合、次のようなものが必要です:

SELECT 
t1.DepartureDateTime AS t1dep,
t2.ArrivalDateTime AS t2arr
, t1.*, t2.*
FROM Table1 t1
INNER JOIN Table1 t2 ON t1.Option = t2.Option AND t1.Option2 = t2.Option2 
WHERE t1.Option3 = (SELECT MIN(Option3) FROM Table1 t3 WHERE t1.Option = t3.Option AND t1.Option2 = t3.Option2)
AND t2.Option3 = (SELECT MAX(Option3) FROM Table1 t3 WHERE t1.Option = t3.Option AND t1.Option2 = t3.Option2)

AND t1.DepartureDateTime BETWEEN '2013-10-01 05:00:00' AND '2013-10-01 07:00:00'
AND t2.ArrivalDateTime BETWEEN '2013-10-04 14:00:00' AND '2013-10-04 15:00:00'

このクエリは、出発の最小日時を返します。これは、旅行の最初の駅の出発日と、1 つの行の最後の駅の到着日を意味します。次に、WHERE句を調整するだけです。

編集: このようなものを探していますか?

SELECT 
l.* FROM
(
SELECT 
`ID`, `DepartureDateTime`, `ArrivalDateTime`, `Departure`, `Arrival`, `Option`, `Option2`, `Option3`
,min_date, counter 
FROM (
SELECT 
t.*,
CASE WHEN `Option` != @prev OR Option2 != @prev2 THEN @min_date := DepartureDateTime ELSE @min_date END as min_date,
CASE WHEN Option2 = @prev2 THEN @counter := @counter + 1 ELSE @counter := 0 END as counter,
@prev := `Option`, @prev2 := Option2
FROM Table1 t 
, (SELECT @min_date:=(SELECT DepartureDateTime FROM Table1 ORDER BY `Option`, Option2, Option3 LIMIT 1), @counter:=0, @prev:=NULL, @prev2:=NULL) vars
order by `Option`, Option2, Option3
) sq
) l 
INNER JOIN
(SELECT `Option`, Option2 FROM Table1 WHERE DepartureDateTime BETWEEN '2013-10-02 11:30:00' AND '2013-10-02 13:00:00'
                          OR ArrivalDateTime BETWEEN '2013-10-03 14:00:00' AND '2013-10-03 14:15:00'
) r
ON l.`Option` = r.`Option` AND l.Option2 = r.Option2
ORDER BY min_date, counter
于 2013-07-30T10:09:53.283 に答える