Sự khác biệt giữa Joins trái, phải, bên ngoài và bên trong là gì?


562

Tôi tự hỏi làm thế nào để phân biệt tất cả các tham gia khác nhau này ...



3
Cũng tùy thuộc vào mức độ hiểu biết của bạn, đối với một người như bạn, bài viết đó không làm gì ngoài một người có thể không hiểu đầy đủ về việc tham gia thì điều đó khá rõ ràng
SQLMenace

6
Đây là bản sao của stackoverflow.com/questions/419375/sql-join-differences và không còn nghi ngờ gì nữa ...
cletus

1
Điều này giúp tôi rất nhiều ... cách dễ nhất là làm bàn thử và chơi với chúng. = P
daGrevis

Câu trả lời:


797

Ví dụ đơn giản : Hãy nói rằng bạn có một Studentsbảng và một Lockersbảng. Trong SQL, bảng đầu tiên bạn chỉ định trong một liên kết Students, là bảng TRÁI và bảng thứ hai Lockers, là bảng ĐÚNG .

Mỗi sinh viên có thể được chỉ định cho một tủ khóa, vì vậy có một LockerNumbercột trong Studentbảng. Nhiều hơn một học sinh có thể có khả năng ở trong một tủ khóa duy nhất, nhưng đặc biệt là vào đầu năm học, bạn có thể có một số học sinh đến mà không có tủ khóa và một số tủ khóa không có học sinh được chỉ định.

Vì lợi ích của ví dụ này, giả sử bạn có 100 sinh viên , 70 trong số đó có tủ khóa. Bạn có tổng cộng 50 tủ khóa , 40 trong số đó có ít nhất 1 sinh viên và 10 tủ khóa không có sinh viên.

INNER THAM GIA tương đương với " cho tôi xem tất cả các sinh viên có tủ khóa ".
Bất kỳ sinh viên nào không có tủ khóa, hoặc bất kỳ tủ khóa nào không có sinh viên đều bị thiếu.
Trả về 70 hàng

LEFT OUTER THAM GIA sẽ là " cho tôi xem tất cả các sinh viên, với tủ khóa tương ứng của họ nếu họ có ".
Đây có thể là một danh sách sinh viên chung, hoặc có thể được sử dụng để xác định sinh viên không có tủ khóa.
Trả về 100 hàng

RIGHT OUTER THAM GIA sẽ là " cho tôi xem tất cả các tủ khóa, và các sinh viên được chỉ định cho họ nếu có bất kỳ ".
Điều này có thể được sử dụng để xác định các tủ khóa không có sinh viên được chỉ định hoặc các tủ khóa có quá nhiều sinh viên.
Trả về 80 hàng (danh sách 70 sinh viên trong 40 tủ khóa, cộng với 10 tủ không có sinh viên)

FULL OUTER THAM GIA sẽ là ngớ ngẩn và có thể không sử dụng nhiều.
Một cái gì đó như " chỉ cho tôi tất cả sinh viên và tất cả các tủ khóa, và ghép chúng ở nơi bạn có thể "
Trả về 110 hàng (tất cả 100 sinh viên, bao gồm cả những người không có tủ khóa. Cộng với 10 tủ khóa không có sinh viên)

CROSS THAM GIA cũng khá ngớ ngẩn trong kịch bản này.
Nó không sử dụng trường được liên kết lockernumbertrong bảng sinh viên, vì vậy về cơ bản, bạn kết thúc với một danh sách khổng lồ lớn về mọi cặp ghép sinh viên có thể khóa, cho dù nó có thực sự tồn tại hay không.
Trả về 5000 hàng (100 sinh viên x 50 tủ khóa). Có thể hữu ích (với tính năng lọc) làm điểm bắt đầu để kết hợp các sinh viên mới với các tủ khóa trống.


12
Sử dụng ví dụ của bạn, tham gia CROSS sẽ hữu ích như một điểm khởi đầu để tạo các bài tập khóa: bắt đầu với tất cả các kết hợp có thể và sau đó sử dụng các tiêu chí khác để lọc kết quả từ danh sách.
Joel Coehoorn

1
Câu trả lời tốt đẹp. Tôi tin rằng Cross Join thường được sử dụng để tạo dữ liệu thử nghiệm từ một vài hàng khi bạn cần một số lượng lớn hồ sơ.
Eli

6
FULL OUTER THAM GIA có thể hữu ích khi tìm kiếm dữ liệu mồ côi hoặc khi so sánh các phiên bản khác nhau của cùng một bộ dữ liệu.
Lara Dougan

3
Tham gia chéo hay còn gọi là sản phẩm cartesian
JavaRocky

3
Tôi nghĩ làm thế nào bạn bắt đầu truy vấn của bạn ảnh hưởng đến kết quả của loại tham gia. Ví dụ, SELECT * FROM students RIGHT OUTER JOIN lockers...sẽ dẫn đến một kết quả khác hơn SELECT * FROM lockers RIGHT OUTER JOIN students.... Câu trả lời tuyệt vời, nhưng rất thích thấy nó được cập nhật với SQLcác truy vấn đầy đủ
jbmilgrom

141

Có ba loại tham gia cơ bản:

  • INNERtham gia so sánh hai bảng và chỉ trả về kết quả khi có kết quả khớp. Các bản ghi từ bảng 1 được nhân đôi khi chúng khớp với nhiều kết quả trong bảng 2. Tham gia INNER có xu hướng làm cho các tập kết quả nhỏ hơn, nhưng vì các bản ghi có thể được sao chép nên điều này không được đảm bảo.
  • CROSStham gia so sánh hai bảng và trả về mọi sự kết hợp có thể của các hàng từ cả hai bảng. Bạn có thể nhận được rất nhiều kết quả từ loại tham gia này thậm chí có thể không có ý nghĩa, vì vậy hãy thận trọng khi sử dụng.
  • OUTERtham gia so sánh hai bảng và trả về dữ liệu khi có kết quả khớp hoặc giá trị NULL khác. Giống như tham gia INNER, điều này sẽ nhân đôi các hàng trong một bảng khi nó khớp với nhiều bản ghi trong bảng khác. Các tham gia OUTER có xu hướng làm cho các tập kết quả lớn hơn, vì chúng sẽ không tự xóa bất kỳ bản ghi nào khỏi tập hợp. Bạn cũng phải đủ điều kiện tham gia OUTER để xác định thời điểm và nơi để thêm các giá trị NULL:
    • LEFT có nghĩa là giữ tất cả các bản ghi từ bảng 1 bất kể điều gì và chèn giá trị NULL khi bảng thứ 2 không khớp.
    • RIGHT có nghĩa là ngược lại: giữ tất cả các bản ghi từ bảng thứ 2 bất kể điều gì và chèn các giá trị NULL mà bảng thứ 1 không khớp.
    • FULL có nghĩa là giữ tất cả các bản ghi từ cả hai bảng và chèn giá trị NULL vào một trong hai bảng nếu không có kết quả khớp.

Thường thì bạn sẽ thấy OUTERtừ khóa được bỏ qua từ cú pháp. Thay vào đó, nó sẽ chỉ là "TRÁI THAM GIA", "THAM GIA ĐÚNG" hoặc "THAM GIA ĐẦY ĐỦ". Điều này được thực hiện bởi vì các phép nối INNER và CROSS không có ý nghĩa gì đối với TRÁI, PHẢI hoặc ĐẦY ĐỦ, và do đó, những điều này là đủ để tự thể hiện rõ ràng việc tham gia NGOÀI.

Dưới đây là một ví dụ về thời điểm bạn có thể muốn sử dụng từng loại:

  • INNER: Bạn muốn trả về tất cả các bản ghi từ bảng "Hóa đơn", cùng với "Hóa đơn" tương ứng của chúng. Điều này giả định rằng mọi Hóa đơn hợp lệ sẽ có ít nhất một dòng.
  • OUTER: Bạn muốn trả lại tất cả các bản ghi "InvoiceLines" cho một Hóa đơn cụ thể, cùng với các bản ghi "InventoryItem" tương ứng của chúng. Đây là một doanh nghiệp cũng bán dịch vụ, sao cho không phải tất cả InvoiceLines đều có IventoryItem.
  • CROSS: Bạn có một bảng chữ số có 10 hàng, mỗi hàng giữ các giá trị '0' đến '9'. Bạn muốn tạo một bảng phạm vi ngày để tham gia, để bạn kết thúc với một bản ghi cho mỗi ngày trong phạm vi. Bằng cách liên tục CROSS - tham gia bảng này, bạn có thể tạo bao nhiêu số nguyên liên tiếp mà bạn cần (với điều kiện bạn bắt đầu từ 10 đến 1, mỗi lần nối thêm 1 vào số mũ). Sau đó, sử dụng hàm DATEADD () để thêm các giá trị đó vào ngày cơ sở của bạn cho phạm vi.

1
Đẹp. Tôi chỉ thêm rằng thông thường nếu bạn chỉ viết 'THAM GIA' thì có nghĩa là THAM GIA.
matpop

47

Chỉ có 4 loại:

  1. Tham gia bên trong : Loại phổ biến nhất. Một hàng đầu ra được tạo ra cho mỗi cặp hàng đầu vào khớp với các điều kiện nối.
  2. Nối ngoài bên trái : Giống như nối bên trong, ngoại trừ nếu có bất kỳ hàng nào không có hàng khớp nào trong bảng bên phải, một hàng là đầu ra chứa các giá trị từ bảng bên trái, với NULLmỗi hàng giá trị trong bảng bên phải. Điều này có nghĩa là mỗi hàng từ bảng bên trái sẽ xuất hiện ít nhất một lần trong đầu ra.
  3. Nối ngoài phải : Giống như nối ngoài trái, ngoại trừ vai trò của các bảng được đảo ngược.
  4. Tham gia bên ngoài đầy đủ : Một sự kết hợp của tham gia bên ngoài bên trái và bên phải. Mỗi hàng từ cả hai bảng sẽ xuất hiện trong đầu ra ít nhất một lần.

"Tham gia chéo" hoặc "tham gia cartesian" chỉ đơn giản là một phép nối bên trong mà không có điều kiện nối nào được chỉ định, dẫn đến tất cả các cặp hàng được xuất ra.

Cảm ơn RusselH vì đã chỉ ra FULL tham gia, điều mà tôi đã bỏ qua.


1
những gì về tham gia bên ngoài đầy đủ và tham gia chéo (sản phẩm của Cartesian)?
SQLMenace

đầy đủ thực sự tương đương với hai lần tham gia bên ngoài
RussellH

25
ĐẦY ĐỦ là những gì bạn nhận được khi kết nối nội bộ của mình và sau đó bạn đặt câu hỏi tại đây "tại sao tôi nhận được N ^ 2 hàng thay vì N"? Sau đó, mọi người sẽ nhận được CROSS tại bạn.
Paul Tomblin

24

Sự khác biệt của SQL THAM GIA:

Rất đơn giản để nhớ:

INNER JOIN Chỉ hiển thị hồ sơ chung cho cả hai bảng.

OUTER JOIN tất cả nội dung của cả hai bảng được hợp nhất với nhau hoặc chúng có khớp hay không.

LEFT JOINgiống như LEFT OUTER JOIN- (Chọn các bản ghi từ bảng đầu tiên (ngoài cùng bên trái) với các bản ghi bảng bên phải phù hợp.)

RIGHT JOINgiống như RIGHT OUTER JOIN- (Chọn các bản ghi từ bảng thứ hai (ngoài cùng bên phải) với các bản ghi bảng bên trái phù hợp.)

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


Có một cách chính xác và phù hợp để gắn nhãn cho vòng tròn biểu đồ Venn, nhưng đây không phải là cách. Các vòng tròn không phải là bảng đầu vào. Ngoài ra, các hàng kết quả không phải là hàng đầu vào, vì vậy mô tả của bạn sai ở đó. Ngoài ra, điều này không rõ ràng - bạn không giải thích "chung cho cả hai", "khớp", "hợp nhất".
philipxy

9

Hãy xem Tham gia (SQL) trên Wikipedia

  • Tham gia bên trong - Cho hai bảng, tham gia bên trong trả về tất cả các hàng tồn tại trong cả hai bảng
  • nối trái / phải (ngoài) - Cho hai bảng trả về tất cả các hàng tồn tại trong bảng bên trái hoặc bên phải của liên kết của bạn, cộng với các hàng từ phía bên kia sẽ được trả về khi mệnh đề nối là khớp hoặc null sẽ được trả về những cột đó

  • Full ngoài - Cho hai bảng trả về tất cả các hàng và sẽ trả về null khi không có cột bên trái hoặc bên phải

  • Cross Joins - Cartesian tham gia và có thể nguy hiểm nếu không được sử dụng cẩn thận


6

Làm cho nó rõ hơn có thể giúp đỡ. Một ví dụ:

Bảng 1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

Ban 2:

ID_STUDENT LOCKER

3               l1
4               l2
5               l3

Những gì tôi nhận được khi tôi làm:

-Inner join of Table 1 and Table 2: 

    - Inner join returns both tables merged only when the key 
      (ID_STUDENT) exists in both tables

    ID_STUDENT       STUDENT_NAME      LOCKER   

        3               Eduardo          l1
        4               Luiz             l2

-Left join of Table 1 and Table 2:

    - Left join merges both tables with all records form table 1, in 
      other words, there might be non-populated fields from table 2

    ID_ESTUDANTE    NOME_ESTUDANTE     LOCKER   

        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2

-Right join of table 1 and table 2:

    - Right join merges both tables with all records from table 2, in 
      other words, there might be non-populated fields from table 1

    ID_STUDENT        STUDENT_NAME     LOCKER   

        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

-Outter join of table 1 and table 2:

    - Returns all records from both tables, in other words, there
      might be non-populated fields either from table 1 or 2.

    ID_STUDENT        STUDENT_NAME     LOCKER   
        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

4

LEFT JOINRIGHT JOINlà các loại OUTER JOINs.

INNER JOIN là mặc định - các hàng từ cả hai bảng phải khớp với điều kiện nối.


5
Tôi không thể tin làm thế nào câu trả lời này có một số upvote và đồng thời nó không đầy đủ.
nbro

Tôi nghĩ rằng đó là một câu trả lời tốt hơn cho câu hỏi ban đầu.
RussellH

3

Tham gia bên trong : Chỉ hiển thị các hàng, khi có dữ liệu từ cả hai bảng.

Nối ngoài : (trái / phải) : Hiển thị tất cả kết quả từ bảng trái / phải với ( các ) hàng được ghép nối , nếu nó tồn tại hay không.


2

Lúc đầu bạn phải hiểu tham gia làm gì? Chúng tôi kết nối nhiều bảng và nhận kết quả cụ thể từ các bảng đã tham gia. Cách đơn giản nhất để làm điều này là tham gia chéo .

Hãy nói rằng bảngA có hai cột A và B. Và bảngB có ba cột C và D. Nếu chúng ta áp dụng nối chéo, nó sẽ tạo ra nhiều hàng vô nghĩa. Sau đó, chúng ta phải khớp bằng khóa chính để lấy dữ liệu thực tế.

Trái: nó sẽ trả về tất cả các bản ghi từ bảng bên trái và bản ghi khớp từ bảng bên phải.

Phải: nó sẽ trở lại đối diện với Tham gia trái. Nó sẽ 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.

Nội tâm: Đây giống như giao lộ. Nó sẽ trả về chỉ các hồ sơ phù hợp từ cả hai bảng.

Bên ngoài: Và điều này giống như công đoàn. Nó sẽ trả về tất cả các bản ghi có sẵn từ cả hai bảng.

Đôi khi chúng ta không cần tất cả dữ liệu và chúng ta chỉ cần dữ liệu chung hoặc hồ sơ. chúng ta có thể dễ dàng có được nó bằng cách sử dụng các phương thức tham gia này. Hãy nhớ tham gia trái và phải cũng là tham gia bên ngoài.

Bạn có thể nhận được tất cả các hồ sơ chỉ bằng cách sử dụng tham gia chéo. Nhưng nó có thể tốn kém khi có hàng triệu hồ sơ. Vì vậy, làm cho nó đơn giản bằng cách sử dụng nối trái, phải, bên trong hoặc bên ngoài.

cảm ơn

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.