วิธีเข้าร่วม INNER ในหลายคอลัมน์


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ประโยคเพื่อให้ตรงกับการเดินทางและเมือง / รหัสปลายทางได้อย่างไร

ด้านล่างนี้เป็น "pseudo-query" เกี่ยวกับสิ่งที่ฉันต้องการให้บรรลุ แต่ฉันไม่สามารถรับไวยากรณ์ได้อย่างถูกต้องและฉันไม่รู้วิธีแสดง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 เข้าร่วมกับงบที่จะมากประโยชน์เช่นคำแนะนำทั่วไปเกี่ยวกับวิธีการสร้างคำสั่ง SQL!


3
คำแนะนำ: คุณต้องค้นหาสองเมืองสำหรับแต่ละระเบียน (หนึ่งรายการสำหรับ fairport และอีกเมืองสำหรับ tairport ดังนั้นจึงเป็นเรื่องปกติ (จำเป็นต้องมี) ที่จะมีJOIN สองตัวพร้อมกับตารางสนามบิน บน tairport
mjv

2
คำแนะนำ 2: คุณจะต้องใช้นามแฝงตารางสนามบินเพื่อให้คุณทราบถึงวิธีแยกแยะพวกเขา (เช่นตารางสนามบินที่มีการค้นหาแฟร์พอร์ตและการค้นหา tairport) คำหลัก SQL สำหรับนามแฝงคือ AS (อาจจะถูกละเว้นนั่นคือ ... เข้าร่วมสนามบิน [AS] FA ON FA.code = flight.tairport ... )
mjv

คำตอบ:


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 to_port ON (to_port.code = flight.tairport) WHERE' ที่บรรทัด 7
Kiril

2
โอ้ฉันรู้ว่าทำไม :) ควรเข้าร่วมภายในไม่ใช่ INNER_JOIN ... DOH!
Kiril

21
หากตารางสนามบินมีขนาดใหญ่ควรเข้าร่วมเพียงครั้งเดียวในหลายเงื่อนไข บางสิ่งบางอย่างที่เหมือน - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportกรุณาแนะนำ
Ankur-m

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มันสร้างความแตกต่างหรือไม่? คุณคิดอย่างไร?
Ankur-m

1
มันสร้างความแตกต่างให้กับผลลัพธ์อดีตสร้างหนึ่งแถวต่อเที่ยวบินด้วยและจากข้อเสนอแนะของคุณจะผลิต 2 แถวต่อเที่ยวบินหนึ่งแถวที่มีจากและหนึ่งไปยังสนามบิน มันจะเร็วกว่าที่จะเข้าร่วมเพียงครั้งเดียวแม้ว่า
Paul Creasey

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

แก้ไข: เพิ่มตัวอย่างเพื่อกรองผลลัพธ์สำหรับรหัสหรือเมือง


11

คุณสามารถใช้และในประโยค?

ตัวอย่างเช่น:

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
วิธีนี้บนโลกถึง 14 upvotes คำสั่งไม่ถูกต้องทั้งในรูปแบบและความหมาย
ultracrepidarian

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
 ...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.