여러 열에서 INNER JOIN을 수행하는 방법


168

숙제 프로젝트를 진행 중이며 도시 이름이나 공항 코드로 항공편을 찾는 데이터베이스 쿼리를 수행해야하지만 flights테이블에는 공항 코드 만 포함되어 있으므로 도시별로 검색하려면 airports테이블 에 조인 하십시오.

공항 테이블에는 다음과 같은 열이 있습니다 code, city
플라이트 (flight) 테이블에는 다음과 같은 열이 있습니다 airline, flt_no, fairport, tairport, depart, arrive, fare
열을 fairport하고 tairport이다 에서 공항 코드.
departarrive출발 및 도착 날짜입니다.

먼저 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의 시각적 표현을매우 SQL 문을 구성하는 방법에 대한 일반적인 가이드로 도움이!


3
힌트 :. 당신은 그것을 그러므로 가지고) (OK 실제로 필요할 때마다 기록합니다 (페어 포트와 tairport 위해 다른 하나를 위해 두 도시를 조회해야하는 공항 테이블과 조인, 그러나 다른 페어 포트를 기반으로 그들 중 하나 에 tairport.
MJV

2
힌트 2 : 따라서 공항 테이블의 별칭을 지정해야 구별 할 수있는 방법을 알 수 있습니다 (예 : 페어 포트 조회 및 공항 조회가있는 공항 테이블). 별명에 대한 SQL 키워드는 AS입니다 (하지만 생략 할 수 있습니다 (예 : ... JOIN 공항 [AS] FA ON FA.code = Flights.tairport ...)
mjv

답변:


141

다음 예제와 같이 조인 된 테이블에 alias 를 지정하여 동일한 테이블로 두 번 이상 JOIN 할 수 있습니다 .

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의 제 2 복사본에 대한 별칭 airports테이블.


좋아, 위의 해결책을 시도하고 다음과 같은 오류가 발생했습니다. SQL 구문에 오류가 있습니다. 7 행에서 'INNER_JOIN 공항 to_port ON (to_port.code = 항공편 .tairport) WHERE'근처에서 사용할 올바른 구문은 MySQL 서버 버전에 해당하는 매뉴얼을 확인하십시오.
Kiril

2
OH, 왜 그런지 알아 :) INNER_JOIN이 아닌 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 = '?'

편집 : 코드 또는 도시의 출력을 필터링하는 예제 추가


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 개의 공감대를 얻었습니까? 구문과 의미가 잘못되었습니다.
ultracrepidarian

3

FROM 및 TO 공항에서 모두 검색하려면 공항 테이블에서 두 번 조인하고 싶을 때 결과 집합에서 출발 및 도착 테이블을 모두 사용할 수 있습니다.

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.