Cara melakukan INNER BERGABUNG di beberapa kolom


168

Saya sedang mengerjakan proyek pekerjaan rumah dan saya seharusnya melakukan query database yang menemukan penerbangan baik dengan nama kota atau kode bandara, tetapi flightstabel hanya berisi kode bandara jadi jika saya ingin mencari berdasarkan kota saya harus bergabunglah di atas airportsmeja.

Tabel bandara memiliki kolom berikut: code, city
Tabel penerbangan memiliki kolom berikut: airline, flt_no, fairport, tairport, depart, arrive, fare
Kolom fairportdan tairportmerupakan kode dari dan ke bandara.
Kolom departdan arrivetanggal keberangkatan dan kedatangan.

Saya datang dengan pertanyaan yang pertama kali bergabung dengan penerbangan pada fairportkolom dan airports.codekolom. Agar saya dapat mencocokkan, tairportsaya harus melakukan join lain pada pertandingan sebelumnya dari join pertama.

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

Permintaan saya mengembalikan hasil yang tepat dan itu sudah cukup untuk keperluan pekerjaan rumah, tapi saya bertanya-tanya apakah saya bisa JOINdi beberapa kolom? Bagaimana saya membuat WHEREklausa sehingga cocok dengan keberangkatan dan kota / kode tujuan?

Di bawah ini adalah "permintaan semu" tentang apa yang ingin saya capai, tetapi saya tidak bisa mendapatkan sintaks dengan benar dan saya tidak tahu bagaimana cara mewakili airportstabel untuk keberangkatan dan tujuan:

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

Memperbarui

Saya juga menemukan representasi visual ini SQL Gabung pernyataan untuk menjadi sangat membantu sebagai panduan umum tentang bagaimana membangun pernyataan SQL!


3
Petunjuk: Anda perlu mencari dua kota untuk setiap record (satu untuk fairport dan yang lainnya untuk tairport. Oleh karena itu OK (memang diperlukan) untuk memiliki dua BERGABUNG, dengan tabel bandara, tetapi satu dari mereka berdasarkan pada fairport yang lain di tairport
mjv

2
Petunjuk 2: Oleh karena itu Anda harus juga alias tabel bandara sehingga Anda tahu bagaimana membedakannya (yaitu yang merupakan tabel bandara dengan pencarian fairport dan dengan pencarian tairport). Kata kunci SQL untuk alias adalah AS (meskipun mungkin dihilangkan, yaitu ... GABUNG bandara [AS] FA ON FA.code = airlines.tairport ...)
mjv

Jawaban:


141

Anda bisa BERGABUNG dengan tabel yang sama lebih dari satu kali dengan memberikan tabel gabungan alias , seperti dalam contoh berikut:

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

Perhatikan bahwa to_portdan from_portmerupakan alias untuk salinan airportstabel pertama dan kedua .


OK, saya mencoba solusi di atas dan pergi kesalahan berikut: Anda memiliki kesalahan dalam sintaks SQL Anda; periksa manual yang sesuai dengan versi server MySQL Anda untuk sintaks yang tepat untuk digunakan di dekat 'INNER_JOIN bandara to_port ON (to_port.code = airlines.tairport) WHERE' di jalur 7
Kiril

2
OH, saya tahu mengapa :) itu seharusnya INNER JOIN bukan INNER_JOIN ... DOH!
Kiril

21
Jika tabel bandara besar, apakah lebih baik untuk bergabung hanya sekali pada kondisi berganda. Sesuatu seperti - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportTolong sarankan.
Ankur-m

26

sesuatu seperti....

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
Saya telah menanyakannya di atas, saya pikir akan menanyakannya di sini juga - Jika tabel bandara sangat besar (DAN ada lebih banyak filter ke seluruh permintaan menggunakan kondisi WHERE), apakah lebih baik untuk bergabung hanya sekali dalam beberapa kondisi. Sesuatu seperti - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportApakah ada bedanya? Bagaimana menurut anda?
Ankur-m

1
Ini membuat perbedaan pada hasil, yang pertama menghasilkan satu baris per penerbangan dengan dari dan ke, saran Anda akan menghasilkan 2 baris per penerbangan, satu baris dengan dari dan satu dengan bandara. Akan lebih cepat untuk bergabung hanya sekali.
Paul Creasey

19

jika mysql tidak apa-apa untuk Anda:

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: menambahkan contoh untuk memfilter output untuk kode atau kota


11

Bisakah Anda menggunakan dan dalam klausa on?

Misalnya, sesuatu seperti:

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
Bagaimana di bumi ini bisa mencapai 14 upvotes? Pernyataan itu salah dalam sintaks dan artinya.
ultracrepidarian

3

Jika Anda ingin mencari di bandara FROM dan TO, Anda harus bergabung di tabel Bandara dua kali - maka Anda dapat menggunakan tabel dari dan ke dalam hasil yang Anda tentukan:

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
 ...
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.