Cách thực hiện THAM GIA VÀO trên nhiều cột


168

Tôi đang làm việc trong một dự án bài tập về nhà và tôi phải thực hiện một truy vấn cơ sở dữ liệu tìm thấy các chuyến bay theo tên thành phố hoặc mã sân bay, nhưng flightsbảng chỉ chứa mã sân bay nên nếu tôi muốn tìm kiếm theo thành phố, tôi phải tìm kiếm tham gia trên airportsbàn

Bảng sân bay có các cột sau: code, city
Bảng chuyến bay có các cột sau: airline, flt_no, fairport, tairport, depart, arrive, fare
Các cột fairporttairporttừđến sân bay.
Các cột departarrivelà ngày khởi hành và đến.

Tôi đã đưa ra một truy vấn đầu tiên tham gia các chuyến bay trên fairportcột vàairports.code cột. Để tôi phù hợp với tairporttôi, tôi phải thực hiện một lần tham gia khác vào các trận đấu trước từ lần tham gia đầu tiên.

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

Truy vấn của tôi trả về kết quả đúng và nó sẽ đủ cho mục đích của bài tập về nhà, nhưng tôi tự hỏi liệu tôi có thể JOIN trên nhiều cột không? Làm thế nào tôi có thể xây dựng WHEREmệnh đề sao cho phù hợp với điểm khởi hành và thành phố / mã đích?

Dưới đây là một "truy vấn giả" về những gì tôi muốn đạt được, nhưng tôi không thể nhận được cú pháp chính xác và tôi không biết làm thế nào để thể hiện airports bảng cho các lần khởi hành và đích đến:

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

Cập nhật

Tôi cũng thấy hình ảnh đại diện này của SQL Tham gia báo cáorất hữu ích như một hướng dẫn chung về cách xây dựng câu lệnh SQL!


3
Gợi ý: Bạn cần tra cứu hai thành phố cho mỗi bản ghi (một cho fairport và một cho tairport. Do đó, thật sự ổn (thực sự cần thiết) để có hai THAM GIA, với bảng sân bay, nhưng một trong số đó dựa trên fairport còn lại trên tairport.
mjv

2
Gợi ý 2: do đó, bạn cũng cần phải đặt bí danh cho bảng sân bay để bạn biết cách phân biệt chúng (nghĩa là bảng sân bay với tra cứu fairport và với tra cứu tairport). Từ khóa SQL cho bí danh là AS (mặc dù nó có thể bị bỏ qua, tức là ... THAM GIA sân bay [AS] FA ON FA.code = chuyến bay.tairport ...)
mjv

Câu trả lời:


141

Bạn có thể THAM GIA với cùng một bảng nhiều lần bằng cách đặt bí danh cho các bảng đã tham gia , như trong ví dụ sau:

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

Lưu ý rằng to_portfrom_portlà bí danh cho các bản sao đầu tiên và thứ hai của airportsbảng.


OK, tôi đã thử giải pháp trên và gặp lỗi sau: Bạn gặp lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết cú pháp phù hợp để sử dụng gần 'INNER_JOIN sân bay to_port ON (to_port.code = chuyến bay.tairport) WHERE' tại dòng 7
Kiril

2
À, tôi biết tại sao :) nó được cho là THAM GIA chứ không phải INNER_JOIN ... DOH!
Kiril

21
Nếu bảng sân bay là rất lớn, tốt hơn là tham gia nó chỉ một lần với nhiều điều kiện. Một cái gì đó như - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportXin đề nghị.
Ankur-m

26

cái gì đó như....

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
Tôi đã hỏi nó ở trên, suy nghĩ cũng sẽ hỏi nó ở đây - Nếu bảng sân bay rất lớn (VÀ có nhiều bộ lọc hơn cho toàn bộ truy vấn bằng điều kiện WHERE), tốt hơn là nên tham gia nó chỉ một lần với nhiều điều kiện. Một cái gì đó như - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairportNó có làm cho bất kỳ sự khác biệt? Bạn nghĩ sao?
Ankur-m

1
Nó tạo ra sự khác biệt cho kết quả, trước đây tạo ra một hàng trên mỗi chuyến bay từ và đến, đề xuất của bạn sẽ tạo ra 2 hàng trên mỗi chuyến bay, một hàng với từ và một với sân bay. Nó sẽ nhanh hơn để tham gia chỉ một lần mặc dù.
Paul Creasey

19

Nếu mysql ổn cho bạn:

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

chỉnh sửa: thêm ví dụ để lọc đầu ra cho mã hoặc thành phố


12

Bạn có thể chỉ sử dụng và trong mệnh đề trên?

Ví dụ: một cái gì đó như:

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
Làm thế nào trên trái đất này có được đến 14 upvote? Tuyên bố không chính xác cả về cú pháp và ý nghĩa.
siêu nhân

3

Nếu bạn muốn tìm kiếm trên cả hai sân bay TỪ và ĐẾN, bạn sẽ muốn tham gia vào bảng Sân bay hai lần - sau đó bạn có thể sử dụng cả từ và đến các bảng trong tập kết quả của mình:

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
 ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.