複数の列で内部結合を行う方法


168

私は宿題プロジェクトに取り組んでいて、都市名または空港コードのいずれかでフライトを検索するデータベースクエリを実行することになっていますが、flightsテーブルには空港コードのみが含まれているため、都市で検索するには、airportsテーブルに参加します。

空港のテーブルには、次の列があります。code, city
フライトテーブルには、次の列があります。airline, flt_no, fairport, tairport, depart, arrive, fare
列をfairportしてtairportいるからする空港コード。
departarriveは、出発日と到着日です。

fairport列と列のフライトを最初に結合するクエリを考え出しましたairports.code。私が一致するためtairportには、最初の結合からの以前の一致に対して別の結合を実行する必要があります。

SELECT airline, flt_no, fairport, tairport, depart, arrive, fare
    FROM (SELECT * FROM flights
        INNER JOIN airports
        ON flights.fairport = airports.code
        WHERE (airports.code = '?' OR airports.city='?')) AS matches
    INNER JOIN airports
    ON matches.tairport = airports.code
    WHERE (airports.code = '?' OR airports.city = '?')

私のクエリは適切な結果を返し、宿題の目的には十分ですがJOIN、複数の列でできるかどうか疑問に思っていますか?WHERE出発地と目的地の都市/コードに一致するように句をどのように作成しますか?

以下は、私が達成したいことについての「疑似クエリ」ですが、構文を正しく取得できずairports、出発地と目的地のテーブルを表す方法がわかりません。

SELECT * FROM flights
INNER JOIN airports
ON flights.fairport = airports.code AND flights.tairport = airports.code
WHERE (airports.code = 'departureCode' OR airports.city= 'departureCity') 
    AND (airports.code = 'destinationCode' OR airports.city = 'destinationCity')

更新

また、SQL結合ステートメントのこの視覚的な表現は、SQLステートメントの作成方法に関する一般的なガイドとして非常に役立つことがわかりました。


3
ヒント:レコードごとに2つの都市を検索する必要があります(1つはフェアポート用、もう1つは空港用です。したがって、2つの JOINをAirports テーブルと共に使用しても問題ありませんが、一方はフェアポートに基づいており、もう一方はフェアポートに基づいています)空港
mjv

2
ヒント2:したがって、それらを区別する方法を知るために、airportsテーブルにもエイリアスを設定する必要があります(つまり、フェアポートルックアップとエアポートルックアップを持つ空港テーブルです)。エイリアスのSQLキーワードはASです(ただし、省略される場合があります。つまり... JOIN空港[AS] FA ON FA.code = flights.tairport ...)
mjv

回答:


141

次の例のように、結合されたテーブルにエイリアスを指定すると、同じテーブルに複数回参加できます。

SELECT 
    airline, flt_no, fairport, tairport, depart, arrive, fare
FROM 
    flights
INNER JOIN 
    airports from_port ON (from_port.code = flights.fairport)
INNER JOIN
    airports to_port ON (to_port.code = flights.tairport)
WHERE 
    from_port.code = '?' OR to_port.code = '?' OR airports.city='?'

to_portおよびfrom_portは、airportsテーブルの最初と2番目のコピーのエイリアスであることに注意してください。


OK、私は上記の解決策を試し、次のエラーに行きました。SQL構文にエラーがあります。7行目で「INNER_JOIN空港to_port ON(to_port.code = flights.tairport)WHERE」付近で使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください
Kiril

2
OH、私はその理由を知っています:)それはINNER_JOINではなくINNER JOINであるはずです... DOH!
キリル

21
空港のテーブルが巨大な場合は、複数の条件で1回だけ参加する方がよいでしょう。のようなもの- flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairport提案してください。
Ankur-m

26

何かのようなもの....

SELECT f.*
      ,a1.city as from
      ,a2.city as to
FROM flights f
INNER JOIN airports a1
ON f.fairport = a1. code
INNER JOIN airports a2
ON f.tairport = a2. code

1
上記で質問したので、ここでも質問します。airportsテーブルが巨大な場合(さらに、WHERE条件を使用してクエリ全体にさらに多くのフィルターがある場合)、複数の条件で1回だけ結合する方が良いでしょう。何か- flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportそれは何か違いがありますか?どう思いますか?
Ankur-m

1
結果には違いがあり、前者はfromおよびtoを使用してフライトごとに1行を生成します。提案は、フライトごとに2行を生成し、1行はfromおよびto空港を使用します。ただし、一度だけ参加する方が速いでしょう。
Paul Creasey 2013年

19

mysqlが問題ない場合:

SELECT flights.*, 
       fromairports.city as fromCity, 
       toairports.city as toCity
FROM flights
LEFT JOIN (airports as fromairports, airports as toairports)
ON (fromairports.code=flights.fairport AND toairports.code=flights.tairport )
WHERE flights.fairport = '?' OR fromairports.city = '?'

編集:コードまたは都市の出力をフィルターする例を追加


11

on句でそのまま使用できますか?

たとえば、次のようなものです。

SELECT 
   airline, flt_no, fairport, tairport, depart, arrive, fare
FROM 
   flights
INNER JOIN 
   airports from_port ON (from_port.code = flights.fairport)
   and (to_port.code = flights.tairport)

5
これはいったいどのようにして14の賛成票を得ましたか ステートメントの構文と意味の両方が正しくありません。
超クレピダリアン

3

FROM空港とTO空港の両方を検索する場合は、Airportsテーブルを2回結合する必要があります。結果セットでは、fromテーブルとtoテーブルの両方を使用できます。

SELECT
   Flights.*,fromAirports.*,toAirports.*
FROM
   Flights
INNER JOIN 
   Airports fromAirports on Flights.fairport = fromAirports.code
INNER JOIN 
   Airports toAirports on Flights.tairport = toAirports.code
WHERE
 ...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.