2010-03-05 4 views
32
SELECT airline, airports.icao_code, continent, country, province, city, website 

FROM airlines 
FULL OUTER JOIN airports ON airlines.iaco_code = airports.iaco_code 
FULL OUTER JOIN cities ON airports.city_id = cities.city_id 
FULL OUTER JOIN provinces ON cities.province_id = provinces.province_id 
FULL OUTER JOIN countries ON cities.country_id = countries.country_id 
FULL OUTER JOIN continents ON countries.continent_id = continents.continent_id 

은 말한다 당신은 당신의 SQL 구문에 오류가MySQL이 FULL OUTER JOIN에서 구문 오류를보고하는 이유는 무엇입니까?

; 근처 사용할 수있는 권리 구문에 대한 MySQL 서버 버전에 해당하는 설명서를 확인하십시오 '외부를 airlines.iaco_code에 airports 가입 = airports.iaco_code 전체 외부 조인'라인 4

에서 구문은 바로 내 보인다. 이전에는 조인을 많이 해본 적이 없지만 다양한 ID로 상호 참조되는 테이블의 열이 필요합니다.

+0

에는'FULL OUTER JOIN' 구문은 없습니다 : http://dev.mysql.com/doc/refman/5.0/en/join.html –

답변

61

MySQL에는 FULL OUTER JOIN이 없습니다. 7.2.12. Outer Join Simplification12.2.8.1. JOIN Syntax 참조 : 두 개의 테이블 T1, T2와

:

당신은 UNION (4.0.0에서의)를 사용하여 FULL OUTER JOIN를 에뮬레이션 할 수

세 개의 테이블 T1과
SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 

, t2, t3 :

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
+0

는 거기 당신이 조인에 권하고 싶습니다 튜토리얼? –

+3

당신의 대답은 정말로 정확하지 않습니다. [Xelrach 's answer] (http://stackoverflow.com/a/3357262/52499) 또는 [이 댓글] (http://stackoverflow.com/questions/4796872/full-outer -join-in-mysql # comment21960067_4796911). –

+0

@Cletus, 그들이 공유하는 PK 열에 '중복 된 열 이름'오류가 계속 발생합니다 ... – Awena

11

cletus의 대답이 옳지 않습니다. UNIONFULL OUTER JOIN에 포함될 중복 레코드를 제거합니다. 당신은 같은 것을 사용하여 중복을해야하는 경우 :

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
WHERE t1.id IS NULL 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
WHERE t2.id IS NULL 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
RIGHT JOIN t4 ON t3.id = t4.id 
WHERE t3.id IS NULL; 
+1

충분히 다루기 쉽고 이론적 인 경우 완벽한 솔루션이 아닙니다. 이 방법은'UNION ALL'을 사용하지만'JOIN' 테이블 중 하나의 컬럼이 다른 테이블의 어떤 로우와도 일치 할 수 없다는 것을 확인하기 위해'NULL '인지 확인하는 것) 실제로 존재하는 테이블에 의존합니다 적어도 하나의'NOT NULL' 컬럼. 실제로 "NULL"을 포함하지 않는 컬럼이 없다면,이 접근법은 작동하지 않을 것이다. –

+0

@ MarkAmery : 당신은 좋은 지적을 제기합니다. anti-join이 올바로 작동하려면 WHERE 절의 조건 자 (predicate)가 일치하는 행을 찾으면 NULL이 아니며 우리가 * 알고있는 * (* 보장 된 *) 열 또는 표현식을 참조해야합니다. ** 동등성 ** 비교를 사용하는 join 술어의 특별한 경우에, 동등성 비교는 일치 된 행에 대해 해당 열의 값이 NULL이 아니게 보장합니다. 우리에게 그 보장을주기 위해 평등 비교를 할 필요는 없습니다.조인이 "일치"행에 대해 NULL 값을 허용하면 NULL이 아닌 표현식을 찾아 사용해야합니다. – spencer7593

+1

@MarkAmery :이 쿼리는 NOT NULL 열이있는 테이블에 의존하지 않습니다. 오히려이 쿼리는 "일치"된 행의 열에 NULL이 아닌 값을 보장하기 위해 조인 조건 자 (ON 절의 조건)에 의존합니다. 이것은 NULL 값과 함께 사용될 때 * 동등 비교 * 연산자의 동작에 의존합니다. (foo = NULL은 foo가 NULL 일 때조차 TRUE를 반환하지 않는다는 것을 알고 있습니다.) – spencer7593

0

난 그냥 이것에 대한 트릭을 만들었습니다 :

(select 1 from DUAL) d 
LEFT OUTER JOIN t1 ON t1.id = t2.id 
LEFT OUTER JOIN t2 ON t1.id = t2.id 

점은 이중에서 조회가 수정 포인트를 만드는 것을이며, MySQL은 외부에 가입 할 수 있습니다 그 2 개의 다른 테이블은

1

FULL OUTER JOIN 세 테이블 t1, t2, t3이 필요할 때만 보충하십시오. t1, t2, t3을 차례대로 만들 수 있고 나머지 두 개의 테이블을 조인 한 다음 합집합을 만들 수 있습니다.

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t1.id = t3.id 
UNION 
SELECT * FROM t2 
LEFT JOIN t1 ON t2.id = t1.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t3 
LEFT JOIN t1 ON t3.id = t1.id 
LEFT JOIN t2 ON t3.id = t2.id 
관련 문제