Sự khác biệt giữa nhóm IN IN THAM GIA VÀ NỀN TẢNG THAM GIA


4672

Ngoài ra làm thế nào LEFT JOIN, RIGHT JOINFULL JOINphù hợp với?


64
Trong số các câu trả lời và nhận xét & tài liệu tham khảo của họ bên dưới chỉ có một người thực sự giải thích cách biểu đồ Venn đại diện cho các toán tử: Vùng giao nhau của vòng tròn biểu thị tập hợp các hàng trong A THAM GIA B. Vùng duy nhất cho mỗi vòng tròn biểu thị tập hợp các hàng bạn nhận được bằng cách lấy các hàng của bảng không tham gia vào A THAM GIA B và thêm các cột duy nhất vào bảng khác được đặt thành NULL. (Và hầu hết đưa ra một sự tương ứng không có thật mơ hồ của các vòng tròn với A và B.)
philipxy

1
Nhảy từ các câu trả lời dựa trên lý thuyết dưới đây, sang một ứng dụng trong thế giới thực: Tôi thường làm việc với dữ liệu thử nghiệm, chạy điểm chuẩn trên các thiết kế bộ xử lý. Thường thì tôi muốn so sánh kết quả giữa 2 hoặc nhiều tùy chọn phần cứng. INNER THAM GIA có nghĩa là tôi chỉ thấy các điểm chuẩn đã chạy thành công trong tất cả các thử nghiệm; OUTER THAM GIA có nghĩa là tôi có thể thấy tất cả các thử nghiệm, bao gồm cả những thử nghiệm không chạy được trên một số cấu hình. Điều quan trọng là phải nhìn thấy những thất bại trong các thí nghiệm như vậy, cũng như thành công. Đủ quan trọng đến nỗi tôi đã viết PerlQuery để có được NGOÀI THAM GIA, khi nhiều RDBMS thiếu nó,
Krazy Glew

4
Rất nhiều câu trả lời đã được cung cấp nhưng tôi chưa thấy hướng dẫn này được đề cập. Nếu bạn biết sơ đồ Venn, đây là một hướng dẫn TUYỆT VỜI: blog.codinghorror.com/a-visual-explanation-of-sql-joins Đối với tôi, nó đủ ngắn gọn để đọc nhanh nhưng vẫn nắm bắt được toàn bộ khái niệm và hoạt động tất cả trường hợp rất tốt. Nếu bạn không biết sơ đồ Venn là gì - hãy tìm hiểu chúng. Mất 5-10 phút để làm như vậy và sẽ giúp bất cứ khi nào bạn cần trực quan hóa làm việc với các bộ và quản lý các hoạt động trên các bộ.
DanteTheSmith

15
@DanteTheSmith Không, bị các vấn đề tương tự như sơ đồ ở đây. Xem bình luận của tôi ở trên câu hỏi và bên dưới bài đăng trên blog đó: "Jeff thoái thác blog của anh ấy một vài trang trong các bình luận". Biểu đồ Venn hiển thị các phần tử trong bộ. Chỉ cần cố gắng xác định chính xác các bộ là gì và các yếu tố trong các sơ đồ này. Các tập hợp không phải là bảng và các phần tử không phải là hàng của chúng. Ngoài ra bất kỳ hai bảng có thể được tham gia, vì vậy PK & FK là không liên quan. Tất cả đều không có thật. Bạn đang làm đúng như những gì hàng ngàn người khác đã làm - có một ấn tượng mơ hồ mà bạn (sai) cho rằng có ý nghĩa.
philipxy

3
Chris Tôi khuyên bạn nên đọc bài viết này: directiondatascience.com/ ( ... và xem xét thay đổi lựa chọn của bạn về câu trả lời được chấp nhận (có lẽ là câu trả lời) cho câu trả lời không sử dụng biểu đồ Venn. Câu trả lời hiện đang được chấp nhận là sai lệch quá nhiều người. Tôi kêu gọi bạn làm điều này vì lợi ích của cộng đồng và chất lượng của nền tảng kiến ​​thức của chúng tôi.
Colm Bhandal

Câu trả lời:


6115

Giả sử bạn đang tham gia trên các cột không có bản sao, đây là trường hợp rất phổ biến:

  • Một phép nối bên trong của A và B cho kết quả của A giao nhau B, tức là phần bên trong của giao điểm sơ đồ Venn .

  • Một phép nối ngoài của A và B cho kết quả của A union B, tức là các phần bên ngoài của liên kết sơ đồ Venn.

Ví dụ

Giả sử bạn có hai bảng, mỗi cột có một cột và dữ liệu như sau:

A    B
-    -
1    3
2    4
3    5
4    6

Lưu ý rằng (1,2) là duy nhất đối với A, (3,4) là phổ biến và (5,6) là duy nhất đối với B.

Tham gia nội bộ

Một phép nối bên trong bằng cách sử dụng một trong hai truy vấn tương đương sẽ cho giao điểm của hai bảng, tức là hai hàng chúng có chung.

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

Tham gia bên ngoài bên trái

Một kết nối bên ngoài bên trái sẽ cho tất cả các hàng trong A, cộng với bất kỳ hàng phổ biến nào trong B.

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

Tham gia bên ngoài bên phải

Một kết nối bên ngoài bên phải sẽ cho tất cả các hàng trong B, cộng với bất kỳ hàng phổ biến nào trong A.

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

Tham gia đầy đủ bên ngoài

Một phép nối ngoài đầy đủ sẽ cung cấp cho bạn liên kết của A và B, tức là tất cả các hàng trong A và tất cả các hàng trong B. Nếu một cái gì đó trong A không có mốc thời gian tương ứng trong B, thì phần B là null và ngược lại ngược lại

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5

42
Sẽ tốt hơn nếu tăng ví dụ bằng cách thêm một hàng khác trong bảng B với giá trị 4. Điều này sẽ cho thấy rằng các phép nối bên trong không cần phải bằng không có hàng nào.
softveda

473
Tuy nhiên, một lời giải thích tuyệt vời cho tuyên bố này: Một phép nối ngoài của A và B đưa ra kết quả của A union B, tức là các phần bên ngoài của một biểu đồ venn. không phrased chính xác. Một phép nối ngoài sẽ cho kết quả của A giao với B ngoài một trong các cách sau: tất cả A (nối trái), tất cả B (nối phải) hoặc tất cả A và tất cả B (nối hoàn toàn). Chỉ có kịch bản cuối cùng này thực sự là A union B. Tuy nhiên, một lời giải thích được viết tốt.
Thomas

11
Tôi có đúng rằng FULL THAM GIA là một bí danh của FULL OUTER THAM GIA và LEFT THAM GIA là một bí danh của LEFT OUTER THAM GIA?
Damian

3
có giải thích tuyệt vời và tuyệt vời. nhưng tại sao trong cột b các giá trị không theo thứ tự? tức là 6,5 không phải là 5,6?
Ameer

7
@Ameer, Cảm ơn. Tham gia không đảm bảo đơn hàng, bạn sẽ cần thêm mệnh đề ORDER BY.
Đánh dấu Harrison

734

Các sơ đồ Venn không thực sự làm điều đó cho tôi.

Ví dụ, chúng không thể hiện bất kỳ sự phân biệt nào giữa liên kết chéo và liên kết nội bộ, hay nói chung hơn là cho thấy bất kỳ sự phân biệt nào giữa các loại vị từ tham gia khác nhau hoặc cung cấp một khung để suy luận về cách chúng sẽ hoạt động.

Không có thay thế cho việc hiểu xử lý logic và dù sao thì cũng tương đối đơn giản để nắm bắt.

  1. Hãy tưởng tượng một tham gia chéo.
  2. Đánh giá onmệnh đề đối với tất cả các hàng từ bước 1 giữ những mệnh đề mà vị từ ước tínhtrue
  3. (Chỉ dành cho các kết nối bên ngoài) thêm lại vào bất kỳ hàng bên ngoài nào bị mất trong bước 2.

(NB: Trong thực tế, trình tối ưu hóa truy vấn có thể tìm thấy các cách thực hiện truy vấn hiệu quả hơn so với mô tả logic thuần túy ở trên nhưng kết quả cuối cùng phải giống nhau)

Tôi sẽ bắt đầu với một phiên bản hoạt hình của một tham gia bên ngoài đầy đủ . Giải thích thêm sau đây.

nhập mô tả hình ảnh ở đây


Giải trình

Bảng nguồn

nhập mô tả liên kết ở đây

Đầu tiên bắt đầu với một CROSS JOIN(Sản phẩm AKA Cartesian). Điều này không có một ONmệnh đề và chỉ đơn giản trả về mọi sự kết hợp của các hàng từ hai bảng.

CHỌN A.Colour, B.Colour TỪ MỘT CROSS THAM GIA B

nhập mô tả liên kết ở đây

Các phép nối bên trong và bên ngoài có một vị từ mệnh đề "BẬT".

  • Nội tham gia. Đánh giá điều kiện trong mệnh đề "BẬT" cho tất cả các hàng trong kết quả nối chéo. Nếu đúng trả về hàng đã tham gia. Nếu không thì loại bỏ nó.
  • Còn lại bên ngoài Tham gia. Tương tự như nối bên trong sau đó cho bất kỳ hàng nào trong bảng bên trái không khớp với bất kỳ thứ gì xuất ra với các giá trị NULL cho các cột của bảng bên phải.
  • Bên phải tham gia. Tương tự như nối bên trong sau đó cho bất kỳ hàng nào trong bảng bên phải không khớp với bất kỳ thứ gì xuất ra với các giá trị NULL cho các cột của bảng bên trái.
  • Tham gia đầy đủ bên ngoài. Tương tự như nối bên trong, sau đó giữ các hàng không khớp bên trái như trong liên kết ngoài trái và các hàng không khớp phải theo liên kết ngoài phải.

Vài ví dụ

CHỌN A.Colour, B.Colour TỪ MỘT NGƯỜI THAM GIA B ON A.Colour = B.Colour

Trên đây là Equi cổ điển tham gia.

Tham gia nội bộ

Phiên bản hoạt hình

nhập mô tả hình ảnh ở đây

CHỌN A.Colour, B.Colour TỪ MỘT NGƯỜI THAM GIA B TRÊN A.Colour KHÔNG IN ('Green', 'Blue')

Điều kiện nối bên trong không nhất thiết phải là điều kiện bằng và nó không cần tham chiếu các cột từ cả hai (hoặc thậm chí) của các bảng. Đánh giá A.Colour NOT IN ('Green','Blue')trên mỗi hàng của lợi nhuận tham gia chéo.

bên trong 2

CHỌN A.Colour, B.Colour TỪ MỘT NGƯỜI THAM GIA B ONNG 1 = 1

Điều kiện nối ước tính là đúng cho tất cả các hàng trong kết quả nối chéo, vì vậy điều này giống như tham gia chéo. Tôi sẽ không lặp lại hình ảnh của 16 hàng một lần nữa.

CHỌN A.Colour, B.Colour TỪ MỘT TRÁI PHIẾU TRÊN TRÊN BÊN A.Colour = B.Colour

Các liên kết ngoài được đánh giá logic theo cách tương tự như các phép nối bên trong ngoại trừ việc nếu một hàng từ bảng bên trái (đối với tham gia bên trái) không tham gia với bất kỳ hàng nào từ bảng bên phải, tất cả đều được giữ nguyên trong các kết quả với NULLcác giá trị cho cột bên tay phải.

LOJ

CHỌN A.Colour, B.Colour TỪ MỘT TRÁI PHIẾU TRÊN TRÊN BÊN A.Colour = B.Colour WHERE B.Colour LÀ NULL

Điều này chỉ đơn giản là hạn chế kết quả trước đó chỉ trả về các hàng trong đó B.Colour IS NULL. Trong trường hợp cụ thể này, đây sẽ là các hàng được bảo tồn vì chúng không có kết quả khớp trong bảng bên phải và truy vấn trả về hàng đỏ duy nhất không khớp trong bảng B. Điều này được gọi là một chống tham gia.

Điều quan trọng là chọn một cột cho IS NULLthử nghiệm không thể rỗng hoặc điều kiện nối đảm bảo rằng mọi NULLgiá trị sẽ được loại trừ để mẫu này hoạt động chính xác và tránh chỉ đưa các hàng trở lại có NULLgiá trị cho điều đó cột ngoài các hàng không khớp.

loj là null

CHỌN A.Colour, B.Colour TỪ MỘT QUYỀN HẠN

Các kết nối bên ngoài bên phải hoạt động tương tự như các liên kết bên ngoài bên trái ngoại trừ chúng bảo toàn các hàng không khớp từ bảng bên phải và null mở rộng các cột bên trái.

ROJ

CHỌN A.Colour, B.Colour TỪ MỘT NGƯỜI NGOÀI ĐẦY ĐỦ THAM GIA B ON A.Colour = B.Colour

Các phép nối ngoài đầy đủ kết hợp hành vi của các phép nối trái và phải và giữ các hàng không khớp từ cả hai bảng bên trái và bên phải.

BÓNG ĐÁ

CHỌN A.Colour, B.Colour TỪ MỘT NGOÀI RA HOÀN TOÀN B ON 1 = 0

Không có hàng nào trong phép nối chéo khớp với 1=0vị ngữ. Tất cả các hàng từ cả hai phía được bảo tồn bằng các quy tắc nối ngoài bình thường với NULL trong các cột từ bảng ở phía bên kia.

BÓNG ĐÁ 2

CHỌN COALESCE (A.Colour, B.Colour) NHƯ Màu TỪ MỘT NGƯỜI NGOÀI ĐẦY ĐỦ THAM GIA B ON 1 = 0

Với một sửa đổi nhỏ cho truy vấn trước, người ta có thể mô phỏng một UNION ALLtrong hai bảng.

ĐOÀN TẤT CẢ

CHỌN A.Colour, B.Colour TỪ MỘT TRÁI PHIẾU TRÊN TRÊN BÊN A.Colour = B.Colour WHERE B.Colour = 'Green'

Lưu ý rằng WHEREmệnh đề (nếu có) chạy một cách hợp lý sau khi nối. Một lỗi phổ biến là thực hiện nối ngoài bên trái và sau đó bao gồm mệnh đề WHERE với một điều kiện trên bảng bên phải kết thúc không bao gồm các hàng không khớp. Ở trên kết thúc việc thực hiện tham gia bên ngoài ...

LOJ

... Và sau đó mệnh đề "Ở đâu" chạy. NULL= 'Green'không đánh giá là đúng vì vậy hàng được bảo tồn bởi phép nối ngoài kết thúc bị loại bỏ (cùng với màu xanh) chuyển đổi hiệu quả phép nối trở lại thành liên kết bên trong.

LOJtoInner

Nếu ý định chỉ bao gồm các hàng từ B trong đó Màu là Xanh lục và tất cả các hàng từ A bất kể cú pháp đúng sẽ là

CHỌN A.Colour, B.Colour TỪ MỘT NGƯỜI TRỞ NÊN TRÊN BÊN A TRÊN A.Colour = B.Colour VÀ B.Colour = 'Green'

nhập mô tả hình ảnh ở đây

Câu đố SQL

Xem các ví dụ này chạy trực tiếp tại SQLFiddle.com .


46
Tôi sẽ nói rằng mặc dù điều này không phù hợp với tôi cũng như các sơ đồ Venn, tôi đánh giá cao rằng mọi người khác nhau và học hỏi khác nhau và đây là một lời giải thích được trình bày rất tốt không giống như bất kỳ tôi đã thấy trước đây, vì vậy tôi ủng hộ @ypercube trao điểm thưởng. Ngoài ra, công việc tốt giải thích sự khác biệt của việc đặt các điều kiện bổ sung trong mệnh đề THAM GIA so với mệnh đề WHERE. Kudos cho bạn, Martin Smith.
Old Pro

22
@OldPro Các sơ đồ Venn vẫn ổn cho đến khi tôi cho rằng nhưng họ im lặng về cách biểu diễn một liên kết chéo hoặc để phân biệt một loại vị từ tham gia như tham gia Equi với một loại khác. Mô hình tinh thần của việc đánh giá vị từ tham gia trên mỗi hàng của kết quả liên kết chéo sau đó thêm lại vào các hàng chưa từng có nếu tham gia bên ngoài và cuối cùng đánh giá nơi phù hợp nhất với tôi.
Martin Smith

18
Các sơ đồ Venn là tốt để đại diện cho Liên minh và Giao lộ và Khác biệt nhưng không tham gia. Chúng có một số giá trị giáo dục nhỏ cho các phép nối rất đơn giản, tức là tham gia trong đó điều kiện nối nằm trên các cột duy nhất.
ypercubeᵀᴹ

12
@Arth - Không, bạn sai. SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155 đây là điều mà sơ đồ Venn không thể minh họa.
Martin Smith

7
@MartinSmith Wow, tôi đồng ý, tôi hoàn toàn sai! Quá quen với việc làm việc với nhiều người .. cảm ơn vì đã sửa chữa.
Khớp

188

Các phép nối được sử dụng để kết hợp dữ liệu từ hai bảng, với kết quả là một bảng mới, tạm thời. Các phép nối được thực hiện dựa trên một thứ gọi là vị ngữ, trong đó chỉ định điều kiện sử dụng để thực hiện phép nối. Sự khác biệt giữa phép nối bên trong và phép nối ngoài là phép nối bên trong sẽ chỉ trả về các hàng thực sự khớp với nhau dựa trên vị từ nối. Ví dụ: Hãy xem xét bảng Nhân viên và Vị trí:

nhập mô tả hình ảnh ở đây

Tham gia bên trong: - Tham gia bên trong tạo bảng kết quả mới bằng cách kết hợp các giá trị cột của hai bảng ( Nhân viên Vị trí ) dựa trên biến vị ngữ tham gia. Truy vấn so sánh từng hàng Nhân viên với từng hàng Vị trí để tìm tất cả các cặp hàng thỏa mãn vị ngữ tham gia. Khi vị từ tham gia được thỏa mãn bằng cách khớp các giá trị không phải NULL, các giá trị cột cho mỗi cặp hàng Nhân viên Vị trí phù hợp sẽ được kết hợp thành một hàng kết quả. Đây là những gì SQL cho một tham gia bên trong sẽ trông như thế nào:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Bây giờ, đây là kết quả của việc chạy SQL đó sẽ như thế nào: nhập mô tả hình ảnh ở đây

Kết nối ngoài: - Một phép nối ngoài không yêu cầu mỗi bản ghi trong hai bảng đã nối phải có bản ghi khớp. Bảng đã tham gia giữ lại từng bản ghi ngay cả khi không có bản ghi khớp nào khác tồn tại. Các liên kết ngoài chia nhỏ hơn nữa thành các liên kết ngoài bên trái và các liên kết ngoài bên phải, tùy thuộc vào các hàng của bảng được giữ lại (trái hoặc phải).

Tham gia bên ngoài bên trái: - Kết quả của việc tham gia bên ngoài bên trái (hoặc đơn giản là tham gia bên trái) cho các bảng Nhân viên Vị trí luôn chứa tất cả các bản ghi của bảng "bên trái" ( Nhân viên ), ngay cả khi điều kiện tham gia không tìm thấy bất kỳ bản ghi phù hợp nào trong bảng "bên phải" ( Vị trí ). Đây là SQL cho phép nối ngoài bên trái trông như thế nào, sử dụng các bảng ở trên:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Bây giờ, đây là kết quả của việc chạy SQL này sẽ như thế nào: nhập mô tả hình ảnh ở đây

Tham gia bên ngoài bên phải: - Tham gia bên ngoài bên phải (hoặc tham gia bên phải) gần giống với tham gia bên ngoài bên trái, ngoại trừ việc xử lý các bảng bị đảo ngược. Mỗi hàng từ bảng "bên phải" ( Vị trí ) sẽ xuất hiện trong bảng đã tham gia ít nhất một lần. Nếu không có hàng phù hợp từ bảng "bên trái" ( Nhân viên ), NULL sẽ xuất hiện trong các cột từ Nhân viên cho những hồ sơ không khớp trong Vị trí . Đây là những gì SQL trông giống như:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

Sử dụng các bảng ở trên, chúng ta có thể hiển thị tập kết quả của phép nối ngoài bên phải sẽ như thế nào:

nhập mô tả hình ảnh ở đây

Tham gia ngoài đầy đủ: - Tham gia đầy đủ bên ngoài hoặc Tham gia đầy đủ là để giữ lại thông tin không khớp bằng cách bao gồm các hàng không khớp trong kết quả của liên kết, sử dụng kết nối ngoài đầy đủ. Nó bao gồm tất cả các hàng từ cả hai bảng, bất kể bảng kia có giá trị khớp hay không.

Nguồn hình ảnh

Hướng dẫn tham khảo MySQL 8.0 - Tham gia Cú pháp

Hoạt động của Oracle


3
câu trả lời tốt nhất cho đến nay, cú pháp thay thế - đó là những gì tôi đang tìm kiếm, cảm ơn!
Joey

1
Các sơ đồ Venn được viết sai. Xem ý kiến ​​của tôi về câu hỏi và câu trả lời khác. Ngoài ra hầu hết các ngôn ngữ này là người nghèo. Ví dụ: "Khi vị từ tham gia được thỏa mãn bằng cách khớp các giá trị không phải NULL, các giá trị cột cho mỗi cặp hàng Nhân viên và Vị trí phù hợp sẽ được kết hợp thành một hàng kết quả." Không, không phải "Khi vị từ tham gia được thỏa mãn bằng cách khớp các giá trị không phải NULL". Các giá trị trong các hàng không quan trọng ngoài việc điều kiện nói chung là đúng hay sai. Một số giá trị cũng có thể là NULL cho một điều kiện thực sự.
philipxy

Mặc dù không được nêu rõ ràng, các sơ đồ trong đây là sơ đồ Venn. Các biểu đồ Venn nói chung không phải là đặc tính toán học chính xác của phép nối. Tôi đề nghị loại bỏ các sơ đồ Venn.
Colm Bhandal

@ColmBhandal: xóa sơ đồ Venn
ajitksharma

Vui lòng sử dụng văn bản, không phải hình ảnh / liên kết, cho văn bản - bao gồm bảng & ERD . Chỉ sử dụng hình ảnh cho những gì không thể được thể hiện dưới dạng văn bản hoặc để tăng thêm văn bản. Hình ảnh không thể được tìm kiếm hoặc cắt và dán. Bao gồm một chú thích / chìa khóa & giải thích với một hình ảnh.
philipxy

133

Tham gia nội bộ

Chỉ lấy các hàng phù hợp, nghĩa là , A intersect B.

Nhập mô tả hình ảnh ở đây

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Bên trái tham gia

Chọn tất cả các bản ghi từ bảng đầu tiên và bất kỳ bản ghi nào trong bảng thứ hai khớp với các phím đã nối.

Nhập mô tả hình ảnh ở đây

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Tham gia đầy đủ bên ngoài

Chọn tất cả các bản ghi từ bảng thứ hai và bất kỳ bản ghi nào trong bảng đầu tiên khớp với các phím đã nối.

Nhập mô tả hình ảnh ở đây

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Người giới thiệu


14
Tên của công cụ là gì? Tôi thấy thật thú vị khi nó hiển thị số lượng hàng và sơ đồ venn
Grijesh Chauhan

2
@GrijeshChauhan Yeah Nhưng bạn có thể thử chạy nó bằng rượu vang .
Tushar Gupta - curioustushar

2
Ồ! vâng tôi ..Tôi sử dụng SQLyog sử dụng rượu vang .. có cũng PlayOnLinux
Grijesh Chauhan

1
Văn bản của bạn không rõ ràng và sai. "Chỉ các hàng được khớp" là các hàng từ liên kết chéo của A & B và những gì được truy xuất (A tham gia bên trong B) không phải là A giao nhau B mà (A bên trái B) giao nhau (A bên phải B). Các hàng "được chọn" không phải từ A & B, chúng là từ A tham gia chéo B & từ các giá trị mở rộng null của các hàng từ A & B.
philipxy 24/07/18

@ TusharGupta-curioustushar bạn nên bao gồm "Các bảng được sử dụng cho các ví dụ SQL"
Manuel Jordan

112

Nói một cách đơn giản:

Một tham gia bên trong chỉ lấy các hàng phù hợp.

Trong khi đó một phép nối ngoài lấy các hàng khớp từ một bảng và tất cả các hàng trong bảng khác .... kết quả phụ thuộc vào việc bạn đang sử dụng cái nào:

  • Trái : Các hàng khớp trong bảng bên phải và tất cả các hàng trong bảng bên trái

  • Phải : Các hàng khớp trong bảng bên trái và tất cả các hàng trong bảng bên phải hoặc

  • Đầy đủ : Tất cả các hàng trong tất cả các bảng. Không có vấn đề gì nếu có trận đấu hay không


1
@nomen Không phải câu trả lời này giải quyết nó, nhưng INNER THAM GIA là một giao điểm và FULL OUTER THAM GIA là ĐOÀN tương ứng nếu các bộ / vòng tròn bên trái và bên phải chứa các hàng (tương ứng) nối TRÁI & PHẢI. PS Câu trả lời này không rõ ràng về các hàng trong đầu vào và đầu ra. Nó nhầm lẫn "trong bảng bên trái / bên phải" với "có phần bên trái / bên phải ở bên trái / bên phải" và nó sử dụng "hàng khớp" với "tất cả" để có nghĩa là hàng được mở rộng bởi hàng từ bảng khác so với null.
philipxy

104

Một kết nối bên trong chỉ hiển thị các hàng nếu có một bản ghi khớp ở phía bên kia (bên phải) của liên kết.

Một kết nối bên ngoài (bên trái) hiển thị các hàng cho mỗi bản ghi ở phía bên trái, ngay cả khi không có hàng phù hợp ở phía bên kia (bên phải) của liên kết. Nếu không có hàng phù hợp, các cột cho phía bên phải (bên phải) sẽ hiển thị NULL.


82

Các phép nối bên trong yêu cầu một bản ghi có ID liên quan tồn tại trong bảng đã nối.

Các kết nối bên ngoài sẽ trả về các bản ghi cho bên trái ngay cả khi không có gì tồn tại cho bên phải.

Chẳng hạn, bạn có một Đơn hàng và bảng OrderDetails. Chúng có liên quan bởi một "OrderID".

Đơn đặt hàng

  • Đặt hàng
  • Tên khách hàng

Đặt hàng chi tiết

  • Đặt hàngDetailID
  • Đặt hàng
  • Tên sản phẩm
  • Số lượng
  • Giá bán

Yêu cầu

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

sẽ chỉ trả về các Đơn hàng cũng có thứ gì đó trong bảng OrderDetails.

Nếu bạn thay đổi nó thành OUTER LEFT THAM GIA

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

sau đó nó sẽ trả về các bản ghi từ bảng Đơn hàng ngay cả khi chúng không có bản ghi OrderDetails.

Bạn có thể sử dụng điều này để tìm các Đơn đặt hàng không có bất kỳ OrderDetails nào chỉ ra một đơn hàng mồ côi có thể bằng cách thêm một mệnh đề where như thế nào WHERE OrderDetails.OrderID IS NULL.


1
Tôi đánh giá cao ví dụ đơn giản nhưng thực tế. Tôi đã thay đổi một yêu cầu như SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASCđể SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL) với thành công. Tôi không chắc chắn về các điều kiện bổ sung, chúng trộn lẫn với nhau ...
PhiLho

68

Nói một cách đơn giản:

Kết nối bên trong -> CHỈ lấy các bản ghi chung từ bảng cha và con WHERE khóa chính của bảng cha khớp với khóa ngoài trong bảng con.

Còn lại tham gia ->

mã giả

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

Tham gia phải : Chính xác đối diện với tham gia trái. Đặt tên của bảng trong LEFT THAM GIA ở bên phải trong Tham gia phải, bạn nhận được đầu ra giống như TRÁI THAM GIA.

Tham gia ngoài : Hiển thị tất cả các bản ghi trong cả hai bảng No matter what. Nếu các bản ghi trong bảng Trái không khớp với bảng bên phải dựa trên khóa Chính, Khóa trước, hãy sử dụng giá trị NULL làm kết quả của phép nối.

Thí dụ :

Thí dụ

Cho phép bây giờ cho 2 bảng

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

Ở đây, bảng nhân viên là bảng Master, phone_numbers_emp NHÂN là bảng con (nó chứa emp_idkhóa ngoại kết nối employee.idvới bảng con của nó.)

Tham gia bên trong

Lấy bản ghi của 2 bảng CHỈ NẾU Khóa chính của bảng nhân viên (id của nó) khớp với khóa ngoài của bảng con phone_numbers_emp NHÂN (emp_id) .

Vì vậy, truy vấn sẽ là:

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Ở đây chỉ lấy các hàng khớp với khóa chính = khóa ngoại như đã giải thích ở trên. Ở đây, các hàng không khớp trên khóa chính = khóa ngoại được bỏ qua do tham gia.

Tham gia trái :

Tham gia bên trái giữ lại tất cả các hàng của bảng bên trái, bất kể có một hàng khớp với bảng bên phải hay không.

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Tham gia bên ngoài :

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Theo sơ đồ, nó trông giống như:

Biểu đồ


4
Kết quả không có gì để (làm theo từng se) với khóa chính / duy nhất / khóa ứng viên & khóa ngoại. Baviour có thể và nên được mô tả mà không cần tham khảo chúng. Một phép nối chéo được tính toán, sau đó các hàng không khớp với điều kiện BẬT được lọc ra; ngoài ra, đối với các hàng tham gia bên ngoài, các hàng được lọc / không
khớp

Giả định rằng các phép nối SQL luôn khớp với các khóa chính / khóa ngoài dẫn đến việc sử dụng sai sơ đồ Venn này. Vui lòng xem lại câu trả lời của bạn cho phù hợp.
Colm Bhandal

58

Bạn sử dụng INNER JOINđể trả về tất cả các hàng từ cả hai bảng có khớp. tức là trong bảng kết quả, tất cả các hàng và cột sẽ có giá trị.

Trong OUTER JOINbảng kết quả có thể có các cột trống. Tham gia bên ngoài có thể LEFThoặc RIGHT.

LEFT OUTER JOIN trả về tất cả các hàng từ bảng đầu tiên, ngay cả khi không có kết quả khớp trong bảng thứ hai.

RIGHT OUTER JOIN trả về tất cả các hàng từ bảng thứ hai, ngay cả khi không có kết quả khớp trong bảng đầu tiên.



54

INNER JOINyêu cầu có ít nhất một trận đấu trong việc so sánh hai bảng. Ví dụ, bảng A và bảng B ngụ ý A ٨ B (A giao nhau B).

LEFT OUTER JOINLEFT JOINgiống nhau Nó cung cấp cho tất cả các bản ghi khớp trong cả hai bảng và tất cả các khả năng của bảng bên trái.

Tương tự, RIGHT OUTER JOINRIGHT JOINgiống nhau. Nó cung cấp cho tất cả các bản ghi khớp trong cả hai bảng và tất cả các khả năng của bảng bên phải.

FULL JOINlà sự kết hợp của LEFT OUTER JOINRIGHT OUTER JOINkhông có sự trùng lặp.


43

Câu trả lời là trong ý nghĩa của từng người, vì vậy trong kết quả.

Lưu ý:
Trong SQLiteđó không có RIGHT OUTER JOINhoặc FULL OUTER JOIN.
Và cũng MySQLkhông có FULL OUTER JOIN.

Câu trả lời của tôi dựa trên Lưu ý ở trên .

Khi bạn có hai bảng như thế này:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

THAM GIA CROSS / NGOÀI THAM GIA:
Bạn có thể có tất cả các dữ liệu bảng đó với CROSS JOINhoặc chỉ với ,như thế này:

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

THAM GIA THAM GIA:
Khi bạn muốn thêm bộ lọc vào các kết quả trên dựa trên mối quan hệ như table1.id = table2.idbạn có thể sử dụng INNER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

TRÁI [NGOÀI] THAM GIA:
Khi bạn muốn có tất cả các hàng của một trong các bảng trong kết quả trên - với cùng một mối quan hệ - bạn có thể sử dụng LEFT JOIN:
(Đối với RIGHT THAM GIA chỉ cần thay đổi vị trí của các bảng)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER THAM GIA:
Khi bạn cũng muốn có tất cả các hàng của bảng khác trong kết quả của mình, bạn có thể sử dụng FULL OUTER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

Vâng, vì nhu cầu của bạn, bạn chọn từng cái đáp ứng nhu cầu của bạn;).


Bạn có thể thêm vào ghi chú của mình rằng không có full outer jointrong MySQL.
potashin

35

Tham gia nội tâm.

Một phép nối được kết hợp các hàng từ hai bảng. Một phép nối bên trong cố gắng khớp hai bảng dựa trên các tiêu chí bạn chỉ định trong truy vấn và chỉ trả về các hàng khớp. Nếu một hàng từ bảng đầu tiên trong phép nối khớp với hai hàng trong bảng thứ hai, thì hai hàng sẽ được trả về trong kết quả. Nếu có một hàng trong bảng đầu tiên không khớp với một hàng trong bảng thứ hai, nó sẽ không được trả về; tương tự, nếu có một hàng trong bảng thứ hai không khớp với một hàng trong bảng đầu tiên, nó sẽ không được trả về.

Tham gia ngoài.

Một liên kết bên trái cố gắng tìm khớp các hàng từ bảng đầu tiên đến các hàng trong bảng thứ hai. Nếu không thể tìm thấy kết quả khớp, nó sẽ trả về các cột từ bảng đầu tiên và để trống các cột từ bảng thứ hai (null).


28

nhập mô tả hình ảnh ở đây

  • INNER JOINtham gia điển hình nhất cho hai hoặc nhiều bảng. Nó trả về kết quả khớp dữ liệu trên cả hai bảng ON quan hệ khóa chính và forignkey.
  • OUTER JOINgiống như INNER JOIN, nhưng nó cũng bao gồm NULLdữ liệu trên result Set.
    • LEFT JOIN= INNER JOIN+ Dữ liệu chưa từng có của bảng bên tráiNull khớp với bảng bên phải.
    • RIGHT JOIN= INNER JOIN+ Dữ liệu chưa từng có của bảng bên phảiNull khớp với bảng bên trái.
    • FULL JOIN= INNER JOIN+ Dữ liệu chưa từng có trên cả hai bảng bên phải và bên tráiNullkhớp.
  • Tự tham gia không phải là một từ khóa trong SQL, khi một bảng tham chiếu dữ liệu tự nó biết là tự tham gia. Sử dụng INNER JOINOUTER JOINchúng ta có thể viết các truy vấn tự tham gia.

Ví dụ:

SELECT * 
FROM   tablea a 
       INNER JOIN tableb b 
               ON a.primary_key = b.foreign_key 
       INNER JOIN tablec c 
               ON b.primary_key = c.foreign_key 

27

Tôi không thấy nhiều chi tiết về hiệu suất và trình tối ưu hóa trong các câu trả lời khác.

Đôi khi thật tốt khi biết rằng chỉ INNER JOINcó liên kết có nghĩa là trình tối ưu hóa có nhiều tùy chọn nhất để chơi với nó. Nó có thể sắp xếp lại thứ tự tham gia để làm cho nó nhanh hơn giữ kết quả tương tự. Trình tối ưu hóa có thể sử dụng các chế độ tham gia nhất.

Nói chung, đó là một thực hành tốt để cố gắng sử dụng INNER JOINthay vì các loại tham gia khác nhau. (Tất nhiên nếu có thể xem xét tập kết quả dự kiến.)

Có một vài ví dụ hay và giải thích ở đây về hành vi kết hợp kỳ lạ này:


4
Nó không thể là "thực hành tốt" để sử dụng một loại tham gia trên một loại khác. Tham gia nào bạn sử dụng xác định dữ liệu mà bạn muốn. Nếu bạn sử dụng một cái khác bạn không chính xác. Thêm vào đó, trong Oracle ít nhất câu trả lời này là hoàn toàn sai. Nghe có vẻ hoàn toàn sai cho mọi thứ và bạn không có bằng chứng. Bạn có bằng chứng không?
Bến

1. Ý tôi là thử dùng. Tôi thấy rất nhiều người sử dụng LEFT OUTER tham gia ở mọi nơi mà không có lý do chính đáng. (Các cột được nối là 'không null'.) Trong những trường hợp đó, chắc chắn sẽ tốt hơn khi sử dụng các phép nối INNER. 2. Tôi đã thêm một liên kết giải thích hành vi không liên kết tốt hơn tôi có thể.
Lajos Veres

Như tôi biết INNER JOINlà chậm hơn so với LEFT JOINhầu hết mọi lúc, Và mọi người có thể sử dụng LEFT JOINthay vì INNER JOINthêm một WHEREđể xóa NULLkết quả không mong muốn ;).
shA.t

Những bình luận này làm tôi hơi không chắc chắn. Tại sao bạn nghĩ INNERlà chậm hơn?
Lajos Veres

Phụ thuộc vào động cơ. tham gia, tham gia, DB2, MySQL. Bẫy hiệu suất rất nhiều, chẳng hạn như gõ lỏng hoặc diễn viên rõ ràng.
mckenzm

26

Đã chỉ trích sơ đồ Venn màu đỏ rất được yêu thích, tôi nghĩ chỉ công bằng khi đăng nỗ lực của mình.

Mặc dù câu trả lời của @Martin Smith là tốt nhất trong nhóm này, nhưng anh ta chỉ hiển thị cột khóa từ mỗi bảng, trong khi tôi nghĩ rằng các cột không khóa cũng lý tưởng cũng nên được hiển thị.

Điều tốt nhất tôi có thể làm trong nửa giờ cho phép, tôi vẫn không nghĩ rằng điều đó cho thấy đầy đủ rằng các null ở đó do không có các giá trị chính trong TableBhoặc đó OUTER JOINthực sự là một liên minh chứ không phải là tham gia:

nhập mô tả hình ảnh ở đây


2
Câu hỏi đang hỏi về sự khác biệt giữa INNER và OUTER tham gia, không nhất thiết phải rời khỏi tham gia bên ngoài lol
LearnByRead

@LearnByRead: hình ảnh của tôi ở bên phải là một kết nối bên ngoài bên phải tức là thay thế TableA a LEFT OUTER JOIN TableB b bằngTableB B RIGHT OUTER JOIN TableA a
onedaywhen

26

Các thuật toán chính xác cho INNER JOIN, LEFT/RIGHT OUTER JOINnhư sau:

  1. Lấy từng hàng từ bảng đầu tiên: a
  2. Xem xét tất cả các hàng từ bảng thứ hai bên cạnh nó: (a, b[i])
  3. Đánh giá ON ...mệnh đề đối với từng cặp:ON( a, b[i] ) = true/false?
    • Khi điều kiện ước tính true, trả về hàng kết hợp đó (a, b[i]).
    • Khi đạt đến cuối bảng thứ hai mà không có bất kỳ trận đấu nào, và đây là một Outer Join cặp (ảo) sau đó sử dụng Nullcho tất cả các cột của bảng khác: (a, Null)cho phép nối ngoài LEFT hoặc (Null, b)cho phép nối ngoài RIGHT. Điều này là để đảm bảo tất cả các hàng của bảng đầu tiên tồn tại trong kết quả cuối cùng.

Lưu ý: điều kiện được chỉ định trong ONmệnh đề có thể là bất cứ điều gì, không bắt buộc phải sử dụng Khóa chính (và bạn không cần phải luôn luôn tham khảo Cột từ cả hai bảng)! Ví dụ:

Tham gia bên trong so với bên trái Tham gia


nhập mô tả hình ảnh ở đây

Ghi chú: Tham gia trái = Tham gia ngoài trái, Tham gia phải = Tham gia ngoài phải.


20

Định nghĩa đơn giản nhất

Tham gia bên trong: Trả về các bản ghi khớp từ cả hai bảng.

Tham gia đầy đủ bên ngoài: Trả về các bản ghi khớp và chưa từng có từ cả hai bảng bằng null cho các bản ghi chưa từng có từ cả hai bảng .

Left Outer Join: Trả về các bản ghi khớp và chưa từng có chỉ từ bảng bên trái .

Right Outer Join: Trả về các bản ghi khớp và chưa từng có từ bảng bên phải .

Nói ngắn gọn

Phù hợp + Trái chưa từng có + Phải chưa từng có = Tham gia ngoài đầy đủ

Phù hợp + Trái chưa từng có = Tham gia ngoài trái

Phù hợp + Phải chưa từng có = Tham gia bên ngoài phải

Phù hợp = Tham gia nội bộ


1
Điều này thật tuyệt vời và giải thích tại sao việc tham gia không hoạt động như mong đợi đối với chỉ số của Time Series. Dấu thời gian cách nhau một giây là vô song.
yeliabsalohcin

1
@yeliabsalohcin Bạn không giải thích "như mong đợi" ở đây hoặc "hoạt động" trong nhận xét của bạn về câu hỏi. Đó chỉ là một số quan niệm sai lầm cá nhân không giải thích được mà bạn mong đợi một cách kỳ lạ. Nếu bạn coi các từ là chậm chạp khi bạn đang đọc - hiểu sai cách viết rõ ràng và / hoặc chấp nhận cách viết không rõ ràng - như khi bạn viết ở đây thì bạn có thể có những quan niệm sai lầm. Trong thực tế, câu trả lời này giống như hầu hết ở đây là không rõ ràng & sai. "Tham gia bên trong: Trả về các bản ghi khớp từ cả hai bảng" là sai khi các bộ cột đầu vào khác nhau. Nó đang cố nói một điều gì đó, nhưng không được . (Xem câu trả lời của tôi.)
philipxy

9

Trong điều khoản đơn giản,

1. THAM GIA THAM GIA HOẶC THIẾT BỊ THAM GIA: Trả về tập kết quả chỉ khớp với điều kiện trong cả hai bảng.

2. OUTER THAM GIA: Trả về tập kết quả của tất cả các giá trị từ cả hai bảng ngay cả khi có điều kiện khớp hay không.

3. TRÁI PHIẾU: Trả về tập kết quả của tất cả các giá trị từ bảng bên trái và chỉ các hàng khớp với điều kiện trong bảng bên phải.

4. RIGHT THAM GIA: Trả về tập kết quả của tất cả các giá trị từ bảng bên phải và chỉ các hàng khớp với điều kiện trong bảng bên trái.

5. FULL THAM GIA: Tham gia đầy đủ và Tham gia đầy đủ bên ngoài là như nhau.


5

Có hai loại chủ yếu là THAM GIA trong SQL: [INNER và OUTER]


Ví dụ

Giả sử bạn có hai bảng, mỗi cột có một cột và dữ liệu như sau:

A    B
-    -
1    3
2    4
3    5
4    6
7
8

Lưu ý rằng (1,2,7,8) là duy nhất đối với A, (3,4) là phổ biến và (5,6) là duy nhất đối với B.



  • (GIỚI THIỆU) THAM GIA :

Từ khóa INNER THAM GIA chọn tất cả các hàng từ cả hai bảng miễn là điều kiện thỏa mãn. Từ khóa này sẽ tạo tập kết quả bằng cách kết hợp tất cả các hàng từ cả hai bảng trong đó điều kiện thỏa mãn tức là giá trị của trường chung sẽ giống nhau.

THAM GIA

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

Kết quả:

a | b
--+--
3 | 3
4 | 4


  • TRÁI (NGOÀI) THAM GIA :

Phép nối này trả về tất cả các hàng của bảng ở phía bên trái của phép nối và các hàng khớp với bảng ở phía bên phải của phép nối. Các hàng không có hàng khớp ở bên phải, tập kết quả sẽ chứa null. THAM GIA TRÁI CÂY còn được gọi là LEFT OUTER JOIN.

THAM GIA TRÁI PHIẾU

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

Kết quả:

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4
7 | null
8 | null


  • RIGHT (OUTER) THAM GIA : Trả về tất cả các bản ghi từ bảng bên phải và các bản ghi khớp từ bảng bên trái

RIGHT THAM GIA / RIGHT OUTER THAM GIA

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

Kết quả:

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6


  • ĐẦY ĐỦ (NGOÀI) THAM GIA :

    FULL THAM GIA tạo ra tập kết quả bằng cách kết hợp kết quả của cả LEFT THAM GIA và RIGHT THAM GIA. Tập kết quả sẽ chứa tất cả các hàng từ cả hai bảng. Các hàng không khớp, tập kết quả sẽ chứa các giá trị NULL.

THAM GIA ĐẦY ĐỦ / ĐẦY ĐỦ THAM GIA

select * from a FULL OUTER JOIN b on a.a = b.b;

Kết quả:

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
   7 | null
   8 | null

1
Các sơ đồ Venn không đủ để mô tả các phép nối SQL trong trường hợp chung. Các phép nối SQL không nhất thiết phải khớp các hàng giữa các bảng một-một, ví dụ: sử dụng khóa ngoại so với khóa chính.
Colm Bhandal

Làm thế nào để bạn tham gia 2 bảng mà không có một hàng phù hợp? Bạn phải cần một khóa chính hoặc khóa ngoài hoặc một số trường chung để bạn có thể thực hiện tham gia. Tôi đang tự hỏi tại sao bạn lại downvote câu trả lời này. Và sơ đồ Venn là nguồn để giải thích cách SQL THAM GIA hoạt động. Bạn có bất kỳ ví dụ tốt hơn để đại diện cho các tham gia? Nếu không, xin vui lòng upvote nó, để mọi người có được giải pháp tốt hơn. Cảm ơn bạn.
Mayur

Bạn là người đưa sơ đồ vào bài viết. Truyền thuyết cho các sơ đồ là gì - Các yếu tố của mỗi bộ là gì? Và những gì về thực tế là bảng là túi không đặt? Bạn không nói. Một điều họ không đặt ra là các hàng A & B trên mỗi nhãn. Xem ý kiến ​​của tôi về các bài viết trên trang này. Bài đăng này chỉ lặp đi lặp lại một cách mù quáng việc sử dụng sai thấy ở nơi khác nhưng không được hiểu hoặc đặt câu hỏi. Ngoài ra những điều bạn nói trong văn bản ở đây không rõ ràng & sai. Ngoài ra nó không thêm gì vào nhiều câu trả lời đã ở đây. (Mặc dù hầu hết tất cả đều khá nghèo nàn.) PS Hãy làm rõ qua các chỉnh sửa, không phải bình luận.
philipxy

FK không cần thiết để tham gia hoặc truy vấn. Bất kỳ 2 bảng nào cũng có thể được nối với bất kỳ điều kiện nào liên quan đến các cột của chúng & bất kể ràng buộc, kích hoạt hoặc xác nhận nào.
philipxy

3
  • Liên kết bên trong - Một kết nối bên trong bằng cách sử dụng một trong hai truy vấn tương đương sẽ cho giao điểm của hai bảng , tức là hai hàng chúng có chung.

  • Nối ngoài trái - Một nối ngoài ngoài trái sẽ cho tất cả các hàng trong A, cộng với bất kỳ hàng phổ biến nào trong B.

  • Tham gia ngoài đầy đủ - Tham gia ngoài đầy đủ sẽ cung cấp cho bạn kết hợp của A và B, tức là Tất cả các hàng trong A và tất cả các hàng trong B. Nếu một cái gì đó trong A không có mốc chuẩn tương ứng trong B, thì phần B là không, và ngược lại


1
Điều này là sai và không rõ ràng. Tham gia không phải là một giao điểm trừ khi các bảng có cùng cột. Các liên kết ngoài không có hàng từ A hoặc B trừ khi chúng có cùng cột, trong trường hợp đó không có null. Bạn đang cố nói điều gì đó, nhưng bạn không nói. Bạn không giải thích chính xác hay rõ ràng.
philipxy

@philipxy: Không đồng ý với tuyên bố của bạn Join is not an intersection unless the tables have the same columns. Bạn có thể tham gia bất kỳ cột nào bạn muốn và nếu giá trị khớp, chúng sẽ tham gia cùng nhau.
SuicideSheep

Nhận xét đó không rõ ràng như câu trả lời của bạn. (Tôi cho rằng bạn có thể đang nghĩ gì đó giống như, tập hợp các giá trị phụ cho các cột chung của kết quả là giao điểm của các tập hợp giá trị phụ cho các cột chung của từng đầu vào; nhưng đó không phải là những gì bạn đã viết. không rõ ràng.)
philipxy

Điều tôi muốn nói là phép nối chỉ là một giao điểm của đầu vào khi nó là phép nối bên trong tự nhiên của các đầu vào có cùng cột. Bạn đang sử dụng sai từ "giao nhau" và "liên minh".
philipxy

3

1. Tham gia bên trong: Còn được gọi là Tham gia. Nó trả về các hàng có trong cả bảng bên trái và bảng bên phải chỉ khi có khớp . Nếu không, nó trả về không có hồ sơ.

Thí dụ:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

đầu ra1

2. Tham gia đầy đủ bên ngoài: Còn được gọi là Tham gia đầy đủ. Nó trả về tất cả các hàng có trong cả bảng bên trái và bảng bên phải.

Thí dụ:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

đầu ra2

3. Tham gia bên ngoài bên trái: Hoặc đơn giản được gọi là Tham gia bên trái. Nó trả về tất cả các hàng có trong bảng bên trái và các hàng khớp từ bảng bên phải (nếu có).

4. Tham gia bên ngoài bên phải: Còn được gọi là Tham gia đúng. Nó trả về các hàng khớp từ bảng bên trái (nếu có) và tất cả các hàng có trong bảng bên phải.

tham gia

Ưu điểm của Joins

  1. Thi công nhanh hơn.

2
Điều này chỉ đúng khi các bảng có cùng một bộ cột. (Nó nhầm lẫn giữa tham gia bên trong với giao lộ & tham gia đầy đủ với công đoàn.) Ngoài ra "kết hợp" không được xác định. Đọc những bình luận khác của tôi.
philipxy

2

Xem xét dưới 2 bảng:

EMP

empid   name    dept_id salary
1       Rob     1       100
2       Mark    1       300
3       John    2       100
4       Mary    2       300
5       Bill    3       700
6       Jose    6       400

Phòng ban

deptid  name
1       IT
2       Accounts
3       Security
4       HR
5       R&D

Tham gia nội bộ:

Chủ yếu được viết là chỉ THAM GIA trong các truy vấn sql. Nó chỉ trả về các bản ghi khớp giữa các bảng.

Tìm hiểu tất cả các nhân viên và tên bộ phận của họ:

Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security

Như bạn thấy ở trên, Josekhông được in từ EMP trong đầu ra vì dept_id 6không tìm thấy kết quả khớp trong bảng Cục. Tương tự, HRR&Dcác hàng không được in từ bảng Cục vì chúng không tìm thấy kết quả khớp trong bảng Emp.

Vì vậy, INNER THAM GIA hoặc chỉ THAM GIA, chỉ trả về các hàng khớp.

CHỖ NỐI BÊN TRÁI :

Điều này trả về tất cả các bản ghi từ bảng TRÁI và chỉ khớp các bản ghi từ bảng ĐÚNG.

Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security
6       Jose    

Vì vậy, nếu bạn quan sát đầu ra ở trên, tất cả các bản ghi từ bảng TRÁI (Emp) được in chỉ với các bản ghi khớp từ bảng PHẢI.

HRR&Dcác hàng không được in từ bảng Cục vì chúng không tìm thấy kết quả khớp trong bảng Emp trên dept_id.

Vì vậy, LEFT THAM GIA trả về TẤT CẢ các hàng từ bảng bên trái và chỉ khớp các hàng từ bảng PHẢI.

Cũng có thể kiểm tra DEMO tại đây .


2

Ý tưởng chung

Xin vui lòng xem câu trả lời của Martin Smith để có minh họa và giải thích tốt hơn về các liên kết khác nhau, bao gồm và đặc biệt là sự khác biệt giữa FULL OUTER JOIN, RIGHT OUTER JOINLEFT OUTER JOIN.

Hai bảng này tạo thành một cơ sở để biểu diễn các JOINs dưới đây:

Nền tảng

THAM GIA

CrossJoin

SELECT *
  FROM citizen
 CROSS JOIN postalcode

Kết quả sẽ là các sản phẩm của Cartesian của tất cả các kết hợp. Không JOINcần điều kiện:

CrossJoinResult

THAM GIA

INNER JOIN cũng giống như đơn giản: JOIN

Nội tâm

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

Kết quả sẽ là các kết hợp thỏa mãn JOINđiều kiện cần thiết :

InsideJoinResult

TRÁI PHIẾU THAM GIA

LEFT OUTER JOIN giống như LEFT JOIN

Chỗ nối bên trái

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

Kết quả sẽ là tất cả mọi thứ citizenngay cả khi không có trận đấu nào postalcode. Một lần nữa một JOINđiều kiện được yêu cầu:

LeftJoinResult

Dữ liệu để chơi

Tất cả các ví dụ đã được chạy trên Oracle 18c. Chúng có sẵn tại dbfiddle.uk , cũng là nơi ảnh chụp màn hình của các bảng.

CREATE TABLE citizen (id      NUMBER,
                      name    VARCHAR2(20),
                      postal  NUMBER,  -- <-- could do with a redesign to postalcode.id instead.
                      leader  NUMBER);

CREATE TABLE postalcode (id      NUMBER,
                         postal  NUMBER,
                         city    VARCHAR2(20),
                         area    VARCHAR2(20));

INSERT INTO citizen (id, name, postal, leader)
              SELECT 1, 'Smith', 2200,  null FROM DUAL
        UNION SELECT 2, 'Green', 31006, 1    FROM DUAL
        UNION SELECT 3, 'Jensen', 623,  1    FROM DUAL;

INSERT INTO postalcode (id, postal, city, area)
                 SELECT 1, 2200,     'BigCity',         'Geancy'  FROM DUAL
           UNION SELECT 2, 31006,    'SmallTown',       'Snizkim' FROM DUAL
           UNION SELECT 3, 31006,    'Settlement',      'Moon'    FROM DUAL  -- <-- Uuh-uhh.
           UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space'   FROM DUAL;

Ranh giới mờ khi chơi với JOINWHERE

THAM GIA

CROSS JOINdẫn đến các hàng là Ý tưởng chung / INNER JOIN:

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

Sử dụng CROSS JOINđể có được kết quả của một LEFT OUTER JOINyêu cầu thủ thuật như thêm vào một NULLhàng. Nó bị bỏ qua.

THAM GIA

INNER JOINtrở thành một sản phẩm cartesian. Nó giống như Ý tưởng chung / CROSS JOIN:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

Đây là nơi tham gia bên trong thực sự có thể được xem là liên kết chéo với kết quả không phù hợp với điều kiện bị xóa. Ở đây không có hàng kết quả được loại bỏ.

Sử dụng INNER JOINđể có được kết quả của một LEFT OUTER JOINcũng đòi hỏi thủ thuật. Nó bị bỏ qua.

TRÁI PHIẾU THAM GIA

LEFT JOINkết quả trong các hàng là Ý tưởng chung / CROSS JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

LEFT JOINkết quả trong các hàng là Ý tưởng chung / INNER JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal
 WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode

Những rắc rối với sơ đồ Venn

Một tìm kiếm trên internet hình ảnh trên "sql tham gia chéo bên trong bên ngoài" sẽ hiển thị vô số biểu đồ Venn. Tôi đã từng có một bản in của một trên bàn của tôi. Nhưng có vấn đề với đại diện.

Biểu đồ Venn là tuyệt vời cho lý thuyết tập hợp, trong đó một phần tử có thể nằm trong một hoặc cả hai tập hợp. Nhưng đối với cơ sở dữ liệu, đối với tôi, một phần tử trong một "tập hợp" dường như là một hàng trong một bảng và do đó cũng không xuất hiện trong bất kỳ bảng nào khác. Không có thứ gọi là một hàng trong nhiều bảng. Một hàng là duy nhất cho bảng.

Tự tham gia là một trường hợp góc trong đó mỗi phần tử trên thực tế là giống nhau trong cả hai bộ. Nhưng nó vẫn không có bất kỳ vấn đề nào dưới đây.

Tập hợp Ađại diện cho tập hợp bên trái ( citizenbảng) và tập hợp Blà tập hợp bên phải ( postalcodebảng) trong cuộc thảo luận dưới đây.

THAM GIA

Mọi yếu tố trong cả hai bộ được khớp với mọi yếu tố trong bộ khác, có nghĩa là chúng ta cần Asố lượng của mọi Byếu tố và Bsố lượng của mọi Ayếu tố để thể hiện đúng sản phẩm Cartesian này. Lý thuyết tập hợp không được tạo cho nhiều phần tử giống hệt nhau trong một tập hợp, vì vậy tôi thấy các sơ đồ Venn để thể hiện chính xác nó không thực tế / không thể. Dường như không UNIONphù hợp chút nào.

Các hàng là khác biệt. Tổng cộng UNIONcó 7 hàng. Nhưng chúng không tương thích với một SQLtập kết quả chung . Và đây không phải là cách một CROSS JOINcông trình hoàn toàn:

CrossJoinUnion1

Cố gắng thể hiện nó như thế này:

CrossJoinUnion2Crossing

..nhưng bây giờ nó trông giống như một cái INTERSECTION, nhưng chắc chắn là không . Hơn nữa, không có yếu tố INTERSECTIONnào thực sự nằm trong bất kỳ hai bộ riêng biệt nào. Tuy nhiên, nó trông rất giống các kết quả có thể tìm kiếm tương tự như sau:

CrossJoinUnionUnion3

Để tham khảo một kết quả có thể tìm kiếm cho CROSS JOINs có thể được nhìn thấy tại Tutorialgateway . Cái INTERSECTION, giống như cái này, trống rỗng.

THAM GIA

Giá trị của một yếu tố phụ thuộc vào JOINđiều kiện. Có thể biểu diễn điều này trong điều kiện mỗi hàng trở nên duy nhất cho điều kiện đó. Ý nghĩa id=xchỉ đúng với một hàng. Khi một hàng trong bảng A( citizen) khớp với nhiều hàng trong bảng B( postalcode) theo JOINđiều kiện, kết quả có cùng các vấn đề như CROSS JOIN: Hàng cần được biểu diễn nhiều lần và lý thuyết tập hợp không thực sự được thực hiện cho điều đó. Trong điều kiện duy nhất, sơ đồ có thể hoạt động, nhưng hãy nhớ rằng JOINđiều kiện xác định vị trí của một phần tử trong sơ đồ. Chỉ nhìn vào các giá trị của JOINđiều kiện với phần còn lại của hàng chỉ để đi xe:

InsideJoinIntersection - Đầy

Đại diện này hoàn toàn tách rời khi sử dụng INNER JOINmột ON 1 = 1điều kiện làm cho nó thành một CROSS JOIN.

Với bản thân JOIN, các hàng trong thực tế là các phần tử lý tưởng trong cả hai bảng, nhưng đại diện cho các bảng là cả hai ABkhông phù hợp lắm. Ví dụ một tự chung JOINđiều kiện mà làm cho một phần tử trong Ađể thể đang khớp khác nhau phần tử trong B ON A.parent = B.child, làm cho trận đấu từ Ađể Bvào các yếu tố riêng biệt. Từ các ví dụ sẽ là SQLnhư thế này:

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

SelfJoinResult

Nghĩa là Smith là thủ lĩnh của cả Green và Jensen.

THAM GIA

Một lần nữa, rắc rối bắt đầu khi một hàng có nhiều kết quả khớp với các hàng trong bảng khác. Điều này còn phức tạp hơn vì OUTER JOINcó thể mặc dù phù hợp với tập hợp trống. Nhưng trong lý thuyết tập hợp, sự kết hợp của bất kỳ tập hợp nào Cvà một tập hợp trống, luôn luôn là như vậy C. Bộ trống không thêm gì. Đại diện của điều này LEFT OUTER JOINthường chỉ hiển thị tất cả Ađể minh họa rằng các hàng trong Ađược chọn bất kể có khớp hay không B. Tuy nhiên, "các yếu tố phù hợp" có cùng các vấn đề như minh họa ở trên. Họ phụ thuộc vào điều kiện. Và bộ trống dường như đã lang thang đến A:

LeftJoinIntersection - Đã điền

Mệnh đề WHERE - có ý nghĩa

Tìm tất cả các hàng từ a CROSS JOINvới Smith và mã bưu chính trên Mặt trăng:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

Ở đâu - kết quả

Bây giờ biểu đồ Venn không được sử dụng để phản ánh JOIN. Nó chỉ được sử dụng cho WHEREmệnh đề:

Ở đâu

.. và điều đó có ý nghĩa.

Khi INTERSECT và UNION có ý nghĩa

GIAO NHAU

Như đã giải thích một INNER JOINkhông thực sự là một INTERSECT. Tuy nhiên INTERSECTs có thể được sử dụng trên các kết quả của các truy vấn riêng biệt. Ở đây một sơ đồ Venn có ý nghĩa, bởi vì các yếu tố từ các truy vấn riêng biệt trên thực tế là các hàng thuộc về một trong hai kết quả hoặc cả hai. Intersect rõ ràng sẽ chỉ trả về kết quả trong đó hàng có mặt trong cả hai truy vấn. Điều này SQLsẽ dẫn đến cùng một hàng như trên WHEREvà biểu đồ Venn cũng sẽ giống nhau:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
INTERSECT
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

LIÊN HIỆP

An OUTER JOINkhông phải là a UNION. Tuy nhiên, UNIONlàm việc trong cùng điều kiện như INTERSECT, dẫn đến trả về tất cả các kết quả kết hợp cả hai SELECT:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
UNION
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

tương đương với:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

..và đưa ra kết quả:

Liên minh - Kết quả

Cũng ở đây một sơ đồ Venn có ý nghĩa:

LIÊN HIỆP

Khi nó không áp dụng

Một lưu ý quan trọng là chúng chỉ hoạt động khi cấu trúc của các kết quả từ hai CHỌN giống nhau, cho phép so sánh hoặc kết hợp. Kết quả của hai điều này sẽ không cho phép:

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

..trying để kết hợp các kết quả với UNIONcung cấp cho một

ORA-01790: expression must have same datatype as corresponding expression

Để biết thêm sự quan tâm, hãy đọc Nói KHÔNG với Biểu đồ Venn khi Giải thích THAM GIAsql tham gia dưới dạng biểu đồ venn . Cả hai cũng che chở EXCEPT.


1

Có rất nhiều câu trả lời hay ở đây với các ví dụ đại số quan hệ rất chính xác . Dưới đây là một câu trả lời rất đơn giản có thể hữu ích cho các lập trình viên nghiệp dư hoặc người mới với các tình huống khó xử về mã hóa SQL.

Về cơ bản, thường xuyên hơn không, các truy vấn JOINcó hai trường hợp:

Đối với SELECTtập hợp con của dữ liệu A:

  • sử dụng INNER JOINkhi dữ liệu liên quan Bbạn đang tìm kiếm PHẢI tồn tại trên mỗi thiết kế cơ sở dữ liệu;
  • sử dụng LEFT JOINkhi dữ liệu liên quan Bbạn đang tìm kiếm MIGHT hoặc MIGHT KHÔNG tồn tại trên mỗi thiết kế cơ sở dữ liệu.

1

Sự khác biệt giữa inner joinouter joinnhư sau:

  1. Inner join là một phép nối kết hợp các bảng dựa trên các bộ dữ liệu phù hợp, trong khi outer join là một phép nối mà bảng kết hợp dựa trên cả bộ dữ liệu khớp và không khớp.
  2. Inner join hợp nhất hàng khớp từ hai bảng trong đó hàng không khớp được bỏ qua, trong khi outer join hợp nhất các hàng từ hai bảng và hàng không với giá trị null.
  3. Inner join giống như một hoạt động giao nhau, trong khi outer join giống như một hoạt động công đoàn.
  4. Inner join là hai loại, trong khi outer join là ba loại.
  5. outer joinnhanh hơn inner join.

1
Một kết quả tham gia bên ngoài giống như tham gia bên trong nhưng cộng với một số hàng bổ sung vì vậy tôi không biết tại sao bạn nghĩ tham gia bên ngoài sẽ nhanh hơn. Ngoài ra những "hai loại" của tham gia bên trong là gì? Tôi cho rằng bạn đang đề cập đến đầy đủ, bên trái và bên phải cho bên ngoài?
Martin Smith

1
@ M.achaibou Vui lòng không thực hiện các chỉnh sửa làm thay đổi định dạng không cần thiết. Tên của các toán tử không phải là mã trừ khi chúng được sử dụng trong mã. Xin đừng thay đổi để đăng ý nghĩa, gửi bình luận cho tác giả. Nếu bạn không có đại diện thì hãy đợi cho đến khi bạn làm được. Nó xảy ra rằng người đăng đã chấp thuận điều này nhưng xin vui lòng không thực hiện các chỉnh sửa như vậy. Tham gia bên ngoài PS không nhanh hơn tham gia bên trong.
philipxy
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.