Birden fazla sütunda bir INNER JOIN nasıl yapılır


168

Ben bir ev ödevi projesi üzerinde çalışıyorum ve şehir adı veya havaalanı kodu ile uçuşlar bulur bir veritabanı sorgusu gerçekleştirmek gerekiyordu, ancak flightstablo sadece havaalanı kodlarını içerir, bu yüzden şehre göre arama yapmak istiyorum eğer airportsmasaya katılmak .

Havaalanları tabloda aşağıdaki sütunlar bulunmaktadır: code, city
uçuşlar tabloda aşağıdaki sütunlar bulunmaktadır: airline, flt_no, fairport, tairport, depart, arrive, fare
sütunlar fairportve tairportvardır den ve karşı havalimanı kodları.
Sütunlar departve arrivekalkış ve varış tarihleri.

Ben ilk fairportsütun ve sütun uçuşlar katılır bir sorgu geldi airports.code. Eşleşebilmem için tairportilk maçtan önceki maçlarda başka bir katılım gerçekleştirmem gerekiyor.

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

Benim sorgu uygun sonuçları döndürür ve ödev amacıyla yeterli olacaktır, ama ben JOINbirden çok sütun üzerinde olup olmadığını merak ediyorum ? WHEREMaddeyi kalkış ve varış şehiriyle / koduyla eşleşecek şekilde nasıl oluşturabilirim ?

Aşağıda ne elde etmek istiyorum üzerinde bir "sözde sorgu", ancak sözdizimini doğru şekilde alamıyorum airportsve gidiş ve hedefler için tablo temsil nasıl bilmiyorum :

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

Güncelleme

Ayrıca SQL deyimleri bu görsel gösterimi SQL deyimleri oluşturma hakkında genel bir kılavuz olarak çok yararlı buldum !


3
İpucu: Her kayıt için iki şehir aramalısınız (biri fuar alanı için, diğeri de tairport için. Bu nedenle havaalanları tablosuyla iki JOIN'e sahip olmak (gerçekten gerekli) , ancak bunlardan biri diğeri fuar alanına dayalı üzerinde tairport.
MJV

2
İpucu2: Bu nedenle, havalimanları tablosunu da nasıl ayırt edeceğinizi bilmeniz gerekir (yani, fairport araması ve tairport araması ile havaalanı masasıdır). Takma ad için SQL anahtar kelimesi AS'dir (her ne kadar göz ardı edilebilirse, yani ... havaalanları [AS] FA ON FA.code = flights.tairport ...)
mjv

Yanıtlar:


141

Aşağıdaki örnekte olduğu gibi , birleştirilen tablolara bir takma ad vererek aynı tabloyla birden çok kez katılabilirsiniz :

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

Not to_portve from_portbirinci ve ikinci kopya rumuzudur airportsmasaya.


Tamam, yukarıdaki çözümü denedim ve aşağıdaki hatayı git: SQL sözdiziminde bir hata var; Doğru sözdizimi için MySQL sunucu sürümüne karşılık yakın kullanmak için o kılavuzuna bakın 'ON to_port INNER_JOIN havaalanlarını (to_port.code = flights.tairport) NEREDE' hattı 7'de
Kiril

2
OH, nedenini biliyorum :) INNER_JOIN değil INNER JOIN olması gerekiyordu ... DOH!
Kiril

22
Havaalanları tablosu çok büyükse, birden fazla koşulda sadece bir kez katılmak daha iyidir. Gibi bir şey - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportLütfen öner.
Ankur-m

26

gibi bir şey....

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
Yukarıda sordum, düşünce de burada soracaktır - Havaalanları tablo büyükse (VE WHERE koşulunu kullanarak tüm sorgu için daha fazla filtre varsa), birden çok durumda sadece bir kez katılmak daha iyidir. Gibi bir şey - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportHerhangi bir fark yaratıyor mu? Ne düşünüyorsun?
Ankur-m

1
Bu, sonuçlarda bir fark yaratır, birincisi uçuş başına ve birinden uçuş başına bir satır üretir, öneriniz uçuş başına 2 satır, bir satırdan ve bir havaalanından havaalanına kadar üretecektir. Yine de sadece bir kez katılmak daha hızlı olurdu.
Paul Creasey

19

mysql sizin için uygunsa:

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: kod veya şehir çıktısını filtrelemek için örnek eklendi


11

Sadece ve on yan tümcesinde kullanabilir misin?

Örneğin, şöyle bir şey:

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
Bu nasıl 14 upvotes aldı? İfade hem sözdizimi hem de anlam bakımından yanlış.
ultracrepidarian

3

Hem FROM hem de TO havaalanlarında arama yapmak istiyorsanız, Havaalanları tablosuna iki kez katılmak istersiniz - o zaman sonuç kümenizdeki hem tablolardan hem de tablolara kullanabilirsiniz:

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
 ...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.