web-dev-qa-db-fra.com

Comment faire une jointure interne sur plusieurs colonnes

Je travaille sur un projet de travail et je suis censé effectuer une requête dans la base de données qui recherche les vols par nom de ville ou code aéroport, mais la table flights ne contient que les codes aéroport. Par conséquent, si je souhaite effectuer une recherche par ville, je dois rejoindre la table airports.

La table airports comprend les colonnes suivantes: code, city
Le tableau des vols contient les colonnes suivantes: airline, flt_no, fairport, tairport, depart, arrive, fare
Les colonnes fairport et tairport sont les de et à codes d’aéroport.
Les colonnes depart et arrive correspondent aux dates de départ et d’arrivée.

Je suis venu avec une requête qui rejoint d'abord les vols sur la colonne fairport et la colonne airports.code. Pour que je puisse faire correspondre la tairport, je dois effectuer une autre jointure lors des matchs précédents de la première.

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

Ma requête renvoie les résultats appropriés et cela suffira pour le travail à faire, mais je me demande si je peux JOIN sur plusieurs colonnes? Comment pourrais-je construire la clause WHERE pour qu'elle corresponde au départ et à la ville/code de destination?

Vous trouverez ci-dessous une "pseudo-requête" sur ce que je veux atteindre, mais je ne parviens pas à obtenir la syntaxe correctement et je ne sais pas comment représenter la table airports pour les départs et les destinations:

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

Mise à jour

J'ai également trouvé que cette représentation visuelle des instructions SQL Join était très utile et servait de guide général pour la construction d'instructions SQL!

152
Kiril

Vous pouvez vous joindre à la même table plusieurs fois en donnant aux tables jointes un alias , comme dans l'exemple suivant:

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

Notez que to_port et from_port sont des alias pour les première et deuxième copies de la table airports.

131
Daniel Vassallo

quelque chose comme....

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
24
Paul Creasey

si mysql vous convient:

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

edit: ajout d'un exemple pour filtrer la sortie par code ou par ville

18
Phil Rykoff

Pouvez-vous simplement utiliser et dans la clause on?

Par exemple, quelque chose comme:

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)
14
ez33

Si vous souhaitez effectuer une recherche à la fois sur les aéroports FROM et TO, vous voudrez vous joindre deux fois au tableau Aéroports - vous pourrez alors utiliser les tableaux from et to dans votre jeu de résultats:

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