MySQL: Phân tích nhanh các loại tham gia


157

Tôi muốn phân tích nhanh các loại tham gia của MySQL. Tôi biết những điều này, phần còn lại tôi không chắc chúng có ý nghĩa gì.

  • dấu phẩy được phân tách ( chính xác thì đây là gì?):SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • hiển thị thông tin từ a, ngay cả khi không có kết quả khớp trong b: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

Tôi đã thấy các phép nối khác, nhưng muốn biết điều gì làm cho chúng khác biệt, cái gì là INNER/ OUTER, không làm LEFTthay đổi mọi thứ.

Tôi đã biết cách tham gia hoạt động, tôi chỉ muốn biết liệu có các loại tham gia khác không, hoặc nếu chúng chỉ là những cách khác nhau để có được kết quả tương tự.


Điều này có trả lời câu hỏi của bạn không? Sự khác biệt giữa "INNER THAM GIA" và "NGOÀI THAM GIA" là gì?
philipxy

Câu trả lời:


463

3
+1 nhưng cả hai đều bị thiếu cross join, một sản phẩm của cartesian.
Denis de Bernardy

11
@denis: hãy xem kỹ hơn về liên kết mã hóa.com:There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:
Rufinus

1
Tôi ngạc nhiên, In sơ đồ này và dán nó lên tường văn phòng của tôi. Bạn đã thay đổi cuộc đời tôi!
yossico

41
Câu hỏi là về MySQL cụ thể. MySQL không hỗ trợ FULL OUTER tham gia.
Mike Baranczak

4
và tất nhiên đây phải là một lý do để không đăng grafic này. thở dài
Rufinus

27

Dựa trên nhận xét của bạn, các định nghĩa đơn giản về từng loại được tìm thấy tốt nhất tại W3Schools Dòng đầu tiên của mỗi loại đưa ra lời giải thích ngắn gọn về loại tham gia

  • THAM GIA: Trả về các hàng khi có ít nhất một trận đấu trong cả hai bảng
  • TRÁI PHIẾU: Trả lại tất cả các hàng từ bảng bên trái, ngay cả khi không có kết quả khớp trong bảng bên phải
  • RIGHT THAM GIA: Trả lại tất cả các hàng từ bảng bên phải, ngay cả khi không có kết quả khớp trong bảng bên trái
  • FULL THAM GIA: Trả về các hàng khi có một trận đấu trong một trong các bảng

EDIT KẾT THÚC

Tóm lại, ví dụ được phân tách bằng dấu phẩy mà bạn đã đưa ra

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

đang chọn mọi bản ghi từ bảng a và b với dấu phẩy ngăn cách các bảng, điều này cũng có thể được sử dụng trong các cột như

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

Sau đó, nó sẽ nhận được thông tin được hướng dẫn trong hàng nơi cột b.id và cột a.beeId có một kết quả khớp trong ví dụ của bạn. Vì vậy, trong ví dụ của bạn, nó sẽ nhận được tất cả thông tin từ các bảng a và b trong đó b.id bằng a.beeId. Trong ví dụ của tôi, nó sẽ nhận được tất cả thông tin từ bảng b và chỉ thông tin từ cột a.beeName khi b.id bằng với a.beeId. Lưu ý rằng cũng có một mệnh đề AND, điều này sẽ giúp tinh chỉnh kết quả của bạn.

Đối với một số hướng dẫn và giải thích đơn giản về các phép nối myQuery và các phép nối trái có một cái nhìn về các hướng dẫn myQuery của Tizag. Bạn cũng có thể xem trang web của Keith J. Brown để biết thêm thông tin về các liên kết cũng khá tốt.

Tôi hy vọng cái này sẽ giúp bạn


Nó xảy ra rằng tôi đã biết tất cả điều đó. Tôi đã thực sự tìm kiếm các loại tham gia mà có. Xin lỗi tôi không rõ về những gì tôi biết. Nhưng tôi đã không tìm kiếm tài liệu dài chỉ để có được bản tóm tắt nhanh chóng.
Bryan Field

Một tài liệu tham khảo khác trong câu trả lời ... có thể là nhiều hơn những gì bạn muốn bạn đời.
Ryan

+1 cho chỉnh sửa đó. Tôi không thiên vị so với W3Schools như một số người dường như. Có lẽ tôi đã không nhìn thấy những mặt xấu nhiều hoặc có lẽ đó chỉ là một "cuộc chiến thần thánh". Ngoài ra, tôi đã chỉnh sửa nội dung từ W3Schools, tôi hy vọng bạn không phiền, nhưng cứ thoải mái thực hiện bất kỳ chỉnh sửa nào bạn thích. Tất cả những hình ảnh trong câu trả lời được chấp nhận là tốt đẹp, nhưng một số thực sự là các biến thể của cùng một tham gia. Đây là một thay thế tốt.
Bryan Field

Cảm ơn George, tôi không bận tâm chút nào, cung cấp bản chỉnh sửa là chính xác! Tôi tin rằng mọi người cần tìm ra những nguồn phù hợp với họ, nhiều hay ít thông tin, rất nhiều ví dụ hoặc không có. W3Schools có chính xác và súc tích, họ cũng có xu hướng có ví dụ tốt, Tizag cũng tương tự. Hãy dễ dàng giao phối
Ryan

1
không có FULL THAM GIA trong mysql, vì vậy các liên kết này không hữu ích lắm.
Ether

13

Tôi có 2 bảng như thế này:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER THAM GIA quan tâm đến cả hai bảng

INNER THAM GIA quan tâm đến cả hai bảng, vì vậy bạn chỉ nhận được một hàng nếu cả hai bảng có một. Nếu có nhiều cặp khớp nhau, bạn sẽ có nhiều hàng.

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

Sẽ không có gì khác biệt với INNER THAM GIA nếu bạn đảo ngược thứ tự, bởi vì nó quan tâm đến cả hai bảng:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

Bạn nhận được các hàng giống nhau, nhưng các cột theo thứ tự khác nhau vì chúng tôi đã đề cập các bảng theo thứ tự khác nhau.

TRÁI PHIẾU chỉ quan tâm đến bảng đầu tiên

LEFT THAM GIA quan tâm đến bảng đầu tiên bạn cung cấp và không quan tâm nhiều đến bảng thứ hai, vì vậy bạn luôn nhận được các hàng từ bảng đầu tiên, ngay cả khi không có hàng tương ứng trong bảng thứ hai:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

Ở trên, bạn có thể thấy tất cả các hàng của bảng_a mặc dù một số trong số chúng không khớp với bất kỳ thứ gì trong bảng b, nhưng không phải tất cả các hàng của bảng_b - chỉ những hàng khớp với thứ gì đó trong bảng_a.

Nếu chúng ta đảo ngược thứ tự của các bảng, LEFT THAM GIA hành xử khác nhau:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

Bây giờ chúng ta nhận được tất cả các hàng của bảng_b, nhưng chỉ khớp với các hàng của bảng_a.

RIGHT THAM GIA chỉ quan tâm đến bảng thứ hai

a RIGHT JOIN bgiúp bạn chính xác các hàng giống như b LEFT JOIN a. Sự khác biệt duy nhất là thứ tự mặc định của các cột.

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

Đây là các hàng giống như table_b LEFT JOIN table_a, mà chúng ta đã thấy trong phần TRÁI PHIẾU.

Tương tự:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

Là các hàng giống như table_a LEFT JOIN table_b.

Không tham gia nào mang lại cho bạn bản sao của tất cả mọi thứ

Mệnh đề không tham gia: Nếu bạn viết các bảng không có mệnh đề THAM GIA, chỉ cần phân tách bằng dấu phẩy, bạn sẽ nhận được mọi hàng của bảng đầu tiên được viết bên cạnh mỗi hàng của bảng thứ hai, trong mọi kết hợp có thể:

> SELECT * FROM table_b, table_a;        
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(Đây là từ bài đăng trên blog của tôi Ví dụ về các loại tham gia SQL )


@Anu Xin đừng thực hiện các chỉnh sửa tầm thường như vậy khi danh tiếng thấp của bạn có nghĩa là các chỉnh sửa của bạn phải được người khác xem xét, bạn chỉ đang lãng phí thời gian của họ. Chỉnh sửa đó nên đã bị từ chối vì không có sự khác biệt. Mã bạn đã thay đổi không thực sự sai và bạn có thể đã nhận xét.
philipxy

@philipxy Được rồi. Lưu ý với điều đó. Trong khi tôi đang cố gắng để hiểu lời giải thích, tôi đã thấy một lỗi đánh máy như vậy và đó là lý do tại sao được chỉnh sửa để làm cho nó rõ ràng hơn. Quả thực đây là một câu trả lời hay và ý định của tôi là giữ cho nó đúng hơn.
Anu

@Anu Câu trả lời này có các mô tả không hoàn chỉnh giống như trong hầu hết các câu trả lời. Nó không thực sự nói đầu ra là một chức năng của đầu vào. Xem hầu hết mọi câu trả lời tại đề xuất trùng lặp & nhận xét của tôi trên cả hai trang. Xem thêm câu trả lời của tôi ở đó. PS Tôi tình cờ chỉ thấy điều này từ ngày hôm qua đã xem xét lại kích thước chỉnh sửa (Tất nhiên có nhiều bài viết liên quan hơn tại Meta Stack Overflow & Meta Stack Exchange .)
philipxy

11

Tham gia đầy đủ bên ngoài không tồn tại trong mysql, bạn có thể cần phải sử dụng kết hợp tham gia trái và phải.

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.