Sự khác biệt giữa THAM GIA VÀO THAM GIA là gì?


35

Tôi chưa quen với SQL và muốn biết sự khác biệt giữa hai JOINloại này là gì?

SELECT * 
FROM user u
INNER JOIN telephone t ON t.user_id = u.id

SELECT * 
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id

Khi nào tôi nên sử dụng cái này hay cái kia?


6
Điều này có phù hợp như một câu hỏi DBA không? Đây có vẻ là một câu hỏi mã hóa hơn đối với tôi.
BlackICE

1
@ Hãy suy nghĩ về Meta
Sathyajith Bhat

@David thì VtC nếu bạn nghĩ nó sai cho trang web. Chúng tôi luôn có thể mở lại.
jcolebrand

3
Tôi nghĩ rằng đây là một câu hỏi tuyệt vời, và rất thích hợp cho trang web.
datagod

điều này cần phải được chuyển ra khỏi DBA, trừ khi một DBA không hoạt động được điều chỉnh để điều chỉnh hiệu suất DB: P
AmDB

Câu trả lời:


32
  • Một phép nối bên trong sẽ chỉ chọn các bản ghi trong đó các khóa được nối nằm trong cả hai bảng được chỉ định.
  • Một kết nối bên ngoài bên trái sẽ 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 khóa đã tham gia.
  • Một kết nối bên ngoài bên phải sẽ 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 khóa đã tham gia.

Trong ví dụ đầu tiên của bạn, bạn sẽ chỉ trả về danh sách người dùng và số điện thoại nếu có ít nhất một bản ghi điện thoại cho người dùng.

Trong ví dụ thứ hai của bạn, bạn sẽ trả về một danh sách tất cả người dùng, cộng với bất kỳ hồ sơ điện thoại nào nếu chúng khả dụng (nếu chúng không có sẵn, bạn sẽ nhận được NULLcác giá trị điện thoại).


13

Bất cứ khi nào ai đó hỏi câu hỏi này, có câu trả lời: http : //www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Hy vọng nó sẽ giúp bạn hiểu,


3
Tôi đã làm việc với những người tham gia trong 20 năm và những sơ đồ đó có vẻ khó hiểu với tôi.
Hogan

3
Tôi với @Hogan - sơ đồ ven không phải là lời giải thích tốt nhất cho điều này .. một lưới hiển thị những kết hợp nào sẽ được trả về có thể sẽ tốt hơn.
Joe

Tất cả những gì cho thấy rằng bạn không hiểu sơ đồ venn. Chúng có liên quan hoàn hảo đến các loại hình tham gia nhưng hãy nhớ rằng chúng là một công cụ giúp hiểu cho những người mới tham gia. Nếu bạn đã học tham gia với một khái niệm khác trong đầu thì chắc chắn bạn sẽ không quen với bạn. Đó không phải là vấn đề, nhưng nó cũng không phải là một chỉ số tốt cho tính hữu ích của sơ đồ.
JamesRyan

@jamesryan điều đó không đúng, chúng không liên quan hoàn hảo, tham gia gần giống với sản phẩm của cartesian, không giao nhau và liên kết, sơ đồ venn tương tự chỉ hoạt động nếu bạn tham gia vào các khóa duy nhất, nếu bạn có các khóa trùng lặp thì bạn mất các khía cạnh sản phẩm cartesian.
Sẽ

1
Tôi hoàn toàn không đồng ý, sơ đồ venn đã có một cách giải thích được xác định rất rõ, thiết lập giao lộ và liên minh. Tham gia không phù hợp với giải thích này khi bạn tham gia vào các khóa không duy nhất. Tôi nghĩ rằng bạn giải thích sơ đồ venn quá rộng.
Sẽ

8

Tham gia bên trong trả về các hàng có thể được kết hợp dựa trên các tiêu chí tham gia.
Tham gia bên ngoài trả về những điều này và tất cả các hàng ...
   ... từ bảng đầu tiên cho tham gia bên trái
   ... từ bảng thứ hai cho tham gia bên phải
   ... từ cả hai bảng để tham gia đầy đủ

Chọn thời điểm sử dụng cái này hay cái kia là vấn đề xác định dữ liệu bạn cần. Ví dụ của bạn nếu bạn chỉ cần các bản ghi có user_ids từ điện thoại khớp với id trong người dùng thì hãy sử dụng phép nối bên trong. Nếu bạn cũng muốn bao gồm các hàng từ người dùng không có mục nhập điện thoại phù hợp, thì tham gia bên trái sẽ phù hợp.

Để biết thêm thông tin hãy xem câu hỏi này trên StackOverflow .


7

Nếu bạn có 2 bảng như dưới đây:

Table1 :   A1    B1          Table2  :    B2     C2 
           -     -                        -      -
           1     2                        1      1
           2     4                        2      4
           3     5                        5      2

Nếu bạn sử dụng Inside Join, bạn sẽ nhận được:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2

Nếu bạn sử dụng Full Outer Tham gia, bạn nhận được:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
NULL   NULL    1       1

Nếu bạn sử dụng Left Outer Tham gia, bạn nhận được:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL

6

Tham gia bên ngoài được thiết kế rõ ràng để tạo ra null trong kết quả của nó và do đó nên tránh, nói chung. Nói một cách tương đối, đó là một kiểu hôn nhân bằng súng ngắn: Nó buộc các bảng thành một loại liên minh. Nó thực hiện điều này, trên thực tế, bằng cách đệm một hoặc cả hai bảng bằng null trước khi thực hiện liên kết, do đó làm cho chúng phù hợp với các yêu cầu thông thường sau khi tất cả. Nhưng không có lý do tại sao việc đệm đó không nên được thực hiện với các giá trị phù hợp thay vì null, như trong ví dụ này:

SELECT SNO , PNO 
FROM   SP 
UNION  
SELECT SNO , 'nil' AS PNO 
FROM   S 
WHERE  SNO NOT IN ( SELECT SNO FROM SP )

Ngoài ra, kết quả tương tự có thể thu được bằng cách sử dụng toán tử nối ngoài SQL kết hợp với COALESCE, như ở đây:

SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO 
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP

Một lưu ý về kết nối ngoài (4.6) trong "Lý thuyết SQL và quan hệ: Cách viết mã SQL chính xác" theo ngày của CJ


5

Một phép nối bên trong là một phép nối trong đó các kết quả duy nhất được hiển thị là các kết quả trong đó các khóa nằm trong cả hai bảng. Một kết nối bên ngoài sẽ hiển thị kết quả cho tất cả các khóa trong một bảng, tham gia bên trái từ lần đầu tiên và tham gia bên phải từ lần thứ hai. Ví dụ:

Giả sử bảng1 có các cặp dữ liệu và khóa chính sau: (1, a), (2, b), (3, c)

Chúng ta cũng nói rằng bảng2 có các cặp dữ liệu và khóa chính sau: (1, vui vẻ), (3, có thể), (4, xảy ra)

Vì vậy, một phép nối bên trong của bảng1 đến bảng2 trên các khóa chính sẽ mang lại các bộ ba kết quả sau (với khóa chính chung đầu tiên, mục thứ hai của bảng thứ hai và mục thứ hai của bảng thứ hai): (1, a, vui vẻ), ( 3, c, có thể)

Một kết nối bên ngoài bên trái của bảng1 đến bảng2 trên các khóa chính sẽ mang lại các bộ ba kết quả sau (cùng định dạng như trên): (1, a, vui vẻ), (2, b, NULL), (3, c, can)

Một kết nối bên ngoài bên phải của bảng1 đến bảng2 trên các khóa chính sẽ mang lại các bộ ba kết quả sau (cùng định dạng như trên): (1, a, vui vẻ), (3, c, can), (4, NULL, xảy ra)

Tôi hy vọng điều này giải thích khái niệm này tốt.


4

Hãy để tôi thử mô tả nó trực quan hơn một chút.

Liên kết bên trong hiển thị cho người dùng, có một hoặc nhiều điện thoại cùng với số điện thoại của họ.

Bên ngoài bên trái tham gia liệt kê thêm những 'người dùng' không có điện thoại.


4

Vì bạn đã hỏi khi nào nên sử dụng cái gì, đây là một kịch bản với các truy vấn - chọn sử dụng tùy thuộc vào yêu cầu.

Dữ liệu:

Người dùng bảng có 10 hồ sơ. Bảng Phoneno có 6 bản ghi (với mối quan hệ 1: 1, nghĩa là một mục trong PhoneNo sẽ chỉ tham chiếu một mục trong Người dùng và chỉ một mục trong PhoneKhông có thể tham chiếu một mục nhập nhất định trong Người dùng).

Yêu cầu 1: Hiển thị tất cả người dùng với số điện thoại của họ. Bỏ qua người dùng mà không có số điện thoại.

Truy vấn:

SELECT u.uid, u.name, p.phonno 
  FROM user u 
INNER JOIN phones p ON p.uid = u.uid

Kết quả: hiển thị 6 người dùng có số điện thoại

Yêu cầu 2: Hiển thị tất cả người dùng với số điện thoại của họ. Nếu người dùng không có màn hình điện thoại 'N / A' (không khả dụng)

Truy vấn:

SELECT u.uid, u.name, ifnull(p.phonno,'N/A') 
  FROM user u 
LEFT OUTER JOIN phones p ON p.uid = u.uid

Kết quả:

Hiển thị tất cả 10 hồ sơ

Lưu ý: ifnull là cú pháp MySql để chuyển đổi giá trị null. Tôi đã sử dụng chức năng này để làm cho công cụ db hiển thị 'N / A' khi phonno là null. Tìm kiếm chức năng phù hợp nếu bạn đang sử dụng một số DBMS khác. Trong SQL Server, bạn phải sử dụng CASEcâu lệnh.

Tôi hi vọng cái này giúp được.

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.