Як зробити внутрішній приєднання на кількох стовпцях


168

Я працюю над проектом домашнього завдання, і я повинен виконувати запит до бази даних, який знаходить рейси або за назвою міста, або з кодом аеропорту, але flightsтаблиця містить лише коди аеропортів, тому якщо я хочу шукати по місту, я повинен приєднайтеся до airportsстолу.

Таблиця аеропортів мають такі стовпці: code, city
Таблиця польотів мають такі стовпці: airline, flt_no, fairport, tairport, depart, arrive, fare
Стовпці fairportі tairportє від і до кодів аеропортів.
Графи departі arriveдати відправлення та прибуття.

Я придумав запит, який спочатку приєднує рейси до 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 Join є дуже корисним як загальне керівництво щодо побудови операторів SQL!


3
Підказка: Вам потрібно знайти два міста для кожного запису (одне для fairport, а інше для tairport. Тому добре (дійсно потрібно) мати два ПРИЄДНАННЯ, зі столом аеропортів, але одне з них засноване на fairport, інше on tairport.
mvv

2
Підказка 2: Тому вам також потрібно буде провести псевдонім таблиці аеропортів, щоб ви знали, як їх розмежувати (тобто, яка є таблиця аеропорту з пошуком Fairport та з пошуку в рейсі). Ключове слово SQL для псевдоніму - AS (хоча воно може бути пропущено, тобто ... ПРИЄДНАЙТЕ до аеропортів [AS] FA ON FA.code = Flights.tairport ...)
mvv

Відповіді:


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таблиці.


Гаразд, я спробував вищевказане рішення і перейшов до наступної помилки: у вас є помилка у вашому синтаксисі SQL; перевірте посібник, який відповідає вашій версії сервера MySQL, чи правильно використовувати синтаксис біля "INNER_JOIN аеропортів до_наключення ON (to_port.code = Letovi.tairport) WHERE" у рядку 7
Кіріл

2
О, я знаю, чому :) це повинно бути ВНУТРІШНЕ ПРИЄДНАННЯ, а не INNER_JOIN ... DOH!
Кирило

21
Якщо стіл аеропортів величезний, краще приєднатись до нього лише один раз у кількох умовах. Щось на зразок - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportбудь ласка, підкажіть.
Анкур-м

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
Я запитав це вище, подумав, запитає його і тут - Якщо таблиця аеропортів величезна (І є більше фільтрів до всього запиту, використовуючи умову WHERE), краще приєднатись до нього лише один раз у кількох умовах. Щось на кшталт - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportчи має це значення? Що ти думаєш?
Анкур-м

1
Це має значення для результатів, коли перший виробляє один ряд на рейс із і до, ваша пропозиція створюватиме 2 ряди на рейс, один ряд - від та один - до аеропорту. Швидше би приєднатися лише один раз.
Пол Крісі

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

редагувати: доданий приклад для фільтрації виводу за кодом або містом


12

Чи можете ви просто використовувати та в пункті 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)

4
Як на Землі це дісталося до 14 версій? Висловлювання невірно як у синтаксисі, так і в значенні.
ультракрепідарій

3

Якщо ви хочете здійснювати пошук як в аеропортах, так і в аеропортах, ви хочете двічі приєднатися до таблиці аеропортів - тоді ви можете використовувати як з, так і з таблиць у наборі результатів:

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
 ...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.