So führen Sie einen INNER JOIN für mehrere Spalten durch

168

Ich arbeite an einem Hausaufgabenprojekt und soll eine Datenbankabfrage durchführen, bei der Flüge entweder anhand des Stadtnamens oder des Flughafencodes gefunden werden. Die flightsTabelle enthält jedoch nur die Flughafencodes. Wenn ich also nach Stadt suchen möchte, muss ich dies tun mach mit auf dem airportsTisch.

Die Flughafentabelle enthält die folgenden Spalten: code, city
Die Flugtabelle enthält die folgenden Spalten: airline, flt_no, fairport, tairport, depart, arrive, fare
Die Spalten fairportund tairportsind die Codes von und nach Flughafen.
Die Spalten departund arrivesind Datum der Abreise und Ankunft.

Ich habe eine Abfrage erstellt, die zuerst die Flüge in der fairportSpalte und in der airports.codeSpalte verbindet. Damit ich mit dem übereinstimmen kann, muss tairportich einen weiteren Join für die vorherigen Matches ab dem ersten Join durchführen.

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 = '?')

Meine Abfrage liefert die richtigen Ergebnisse und reicht für die Hausaufgaben aus. Ich frage mich jedoch, ob ich JOINmehrere Spalten bearbeiten kann. Wie würde ich die WHEREKlausel so konstruieren , dass sie mit der Abfahrt und der Zielstadt / dem Zielcode übereinstimmt?

Unten ist eine "Pseudo-Abfrage" zu dem, was ich erreichen möchte, aber ich kann die Syntax nicht richtig verstehen und ich weiß nicht, wie ich die airportsTabelle für die Abflüge und die Ziele darstellen soll:

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')

Aktualisieren

Ich fand diese visuelle Darstellung von SQL Join-Anweisungen auch sehr hilfreich als allgemeine Anleitung zum Erstellen von SQL-Anweisungen!

Kiril
quelle
3
Tipp: Sie müssen zwei Städte für jeden Datensatz suchen (eine für den Fairport und die andere für den Tairport. Es ist daher in Ordnung (tatsächlich erforderlich), zwei JOINs mit der Flughafentabelle zu haben, aber eine davon basiert auf dem Fairport der anderen auf tairport.
mjv
2
Tipp 2: Sie müssen daher auch die Flughafentabelle aliasen, damit Sie wissen, wie Sie sie unterscheiden können (dh die Flughafentabelle mit der Fairport-Suche und der Tairport-Suche). Das SQL-Schlüsselwort für Alias ​​ist AS (obwohl es weggelassen werden kann, dh ... JOIN Airports [AS] FA ON FA.code = Flights.tairport ...)
mjv

Antworten:

141

Sie können mit derselben Tabelle mehrmals beitreten, indem Sie den verknüpften Tabellen einen Alias ​​geben , wie im folgenden Beispiel:

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='?'

Beachten Sie, dass die to_portund from_portAliase für die erste und zweite Kopie der airportsTabelle sind.

Daniel Vassallo
quelle
OK, ich habe die obige Lösung ausprobiert und den folgenden Fehler ausgeführt: Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, auf die richtige Syntax für die Verwendung in der Nähe von 'INNER_JOIN-Flughäfen to_port ON (to_port.code = flüge.tairport) WHERE' in Zeile 7
Kiril
2
OH, ich weiß warum :) es soll INNER JOIN sein, nicht INNER_JOIN ... DOH!
Kiril
21
Wenn der Tisch am Flughafen riesig ist, ist es besser, nur einmal unter mehreren Bedingungen daran teilzunehmen. So etwas wie - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportBitte vorschlagen.
Ankur-m
26

etwas wie....

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
Paul Creasey
quelle
1
Ich habe es oben gefragt, der Gedanke wird es auch hier fragen - Wenn die Flughafentabelle riesig ist (UND die gesamte Abfrage unter Verwendung der WHERE-Bedingung mehr Filter enthält), ist es besser, sie nur einmal unter mehreren Bedingungen zu verbinden. So etwas wie - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportMacht es einen Unterschied? Was denken Sie?
Ankur-m
1
Es macht einen Unterschied zu den Ergebnissen, die erstere produziert eine Reihe pro Flug mit von und nach, Ihr Vorschlag würde 2 Reihen pro Flug produzieren, eine Reihe mit dem von und eine mit dem zum Flughafen. Es wäre jedoch schneller, nur einmal beizutreten.
Paul Creasey
19

Wenn MySQL für Sie in Ordnung ist:

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 = '?'

Bearbeiten: Beispiel hinzugefügt, um die Ausgabe nach Code oder Stadt zu filtern

Phil Rykoff
quelle
12

Können Sie einfach und in der on-Klausel verwenden?

Zum Beispiel so etwas wie:

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)
ez33
quelle
4
Wie um alles in der Welt kam das zu 14 positiven Stimmen? Die Aussage ist sowohl in der Syntax als auch in der Bedeutung falsch.
Ultracrepidarian
3

Wenn Sie sowohl auf FROM- als auch auf TO-Flughäfen suchen möchten, möchten Sie zweimal an der Airports-Tabelle teilnehmen. Anschließend können Sie sowohl From- als auch To-Tabellen in Ihrer Ergebnismenge verwenden:

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
 ...
MisterZimbu
quelle