2010-03-05 36 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 

Nó nói rằngTại sao MySQL báo cáo lỗi cú pháp trên FULL OUTER JOIN?

Bạn có một lỗi trong cú pháp SQL của bạn; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn cho đúng cú pháp để sử dụng gần 'bên ngoài tham gia airports trên airlines.iaco_code = airports.iaco_code toàn bên ngoài tham gia' tại dòng 4

Cú pháp có vẻ đúng với tôi. Tôi đã không bao giờ thực hiện rất nhiều tham gia trước, nhưng tôi cần những cột trong một bảng được tham chiếu chéo bởi id khác nhau.

+0

Không có cú pháp 'FULL OUTER JOIN': http://dev.mysql.com/doc/refman/5.0/en/join.html –

Trả lời

61

Không có FULL OUTER JOIN trong MySQL. Xem 7.2.12. Outer Join Simplification12.2.8.1. JOIN Syntax:

Bạn có thể bắt chước FULL OUTER JOIN sử dụng UNION (từ MySQL 4.0.0 trên):

với hai bảng t1, t2:

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

với ba bảng t1, 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

Có hướng dẫn bạn muốn giới thiệu về tham gia không? –

+3

Câu trả lời của bạn không thực sự chính xác, xem [Câu trả lời của Xelrach] (http://stackoverflow.com/a/3357262/52499), hoặc [bình luận này] (http://stackoverflow.com/questions/4796872/full-outer -join-in-mysql # comment21960067_4796911). –

+0

@Cletus, tôi tiếp tục gặp lỗi 'Tên cột trùng lặp' trên cột PK họ chia sẻ ... – Awena

11

Câu trả lời của cletus không hoàn toàn đúng. UNION sẽ xóa các bản ghi trùng lặp mà FULL OUTER JOIN sẽ bao gồm. Nếu bạn cần bản sao sử dụng cái gì đó như:

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

Lưu ý rằng - nếu bạn đủ thông tin và lý thuyết - đây không phải là giải pháp hoàn hảo. Cách tiếp cận này (sử dụng 'UNION ALL' nhưng kiểm tra nếu một cột trong một trong các bảng' JOIN'ed là 'NULL' để xác định rằng nó không thể khớp với bất kỳ hàng nào trong các bảng khác). ít nhất một cột 'NOT NULL'. Nếu không có cột nào được đảm bảo không * thực sự * chứa một 'NULL', phương pháp này sẽ không hoạt động. –

+0

@MarkAmery: Bạn nâng cao điểm tốt. Để chống tham gia hoạt động chính xác, biến vị ngữ trong mệnh đề WHERE cần tham chiếu một cột hoặc biểu thức mà chúng ta biết * (rằng chúng ta * được bảo đảm *) sẽ không là NULL nếu tìm thấy một hàng phù hợp. Trong trường hợp đặc biệt của biến vị ngữ nối sử dụng phép so sánh ** bình đẳng **, phép so sánh bình đẳng đó đảm bảo cho chúng ta rằng giá trị của cột đó sẽ không là NULL cho các hàng phù hợp. Nó không phải so sánh bình đẳng để đảm bảo cho chúng tôi.Nếu tham gia không cho phép các giá trị NULL cho các hàng "phù hợp", chúng ta phải tìm/sử dụng một biểu thức không NULL. – spencer7593

+1

@MarkAmery: Truy vấn này không dựa vào các bảng có cột NOT NULL. Thay vào đó, truy vấn này dựa vào vị từ nối (điều kiện trong mệnh đề ON) để đảm bảo một giá trị không NULL cho một cột trong một hàng "phù hợp". Điều này dựa vào hành vi của toán tử * so sánh * khi được sử dụng với các giá trị NULL. (Chúng ta biết rằng 'foo = NULL' sẽ không trả về TRUE, ngay cả khi' foo IS NULL'.) – spencer7593

0

Tôi đã chỉ cần thực hiện một thủ thuật cho việc này:

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

điểm mấu chốt là, rằng các truy vấn từ kép làm cho một điểm sửa chữa, và mysql có thể bên ngoài tham gia 2 bảng khác cho rằng

1

Chỉ bổ sung trường hợp khi bạn cần FULL OUTER JOIN ba bảng t1, t2, t3. Bạn có thể làm cho t1, t2, t3, lần lượt, trái tham gia phần còn lại hai bảng, sau đó liên minh.

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 
Các vấn đề liên quan