Làm thế nào một LEFT OUTER THAM GIA có thể trả lại nhiều hồ sơ hơn so với tồn tại trong bảng bên trái?


165

Tôi có một LEFT OUTER THAM GIA rất cơ bản để trả về tất cả các kết quả từ bảng bên trái và một số thông tin bổ sung từ một bảng lớn hơn nhiều. Bảng bên trái chứa 4935 bản ghi khi tôi TRỞ NÊN THAM GIA nó vào một bảng bổ sung, số lượng bản ghi lớn hơn đáng kể.

Theo như tôi biết, một tin mừng tuyệt đối rằng LEFT OUTER THAM GIA sẽ trả lại tất cả các bản ghi từ bảng bên trái với các bản ghi khớp từ bảng bên phải và các giá trị null cho bất kỳ hàng nào không thể khớp, vì vậy tôi hiểu rằng nó nên không thể trả lại nhiều hàng hơn tồn tại trong bảng bên trái, nhưng điều đó xảy ra hoàn toàn giống nhau!

Truy vấn SQL sau:

SELECT     SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM         SUSP.Susp_Visits LEFT OUTER JOIN
                      DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum

Có lẽ tôi đã mắc lỗi trong cú pháp hoặc sự hiểu biết của tôi về LEFT OUTER THAM GIA là không đầy đủ, hy vọng ai đó có thể giải thích làm thế nào điều này có thể xảy ra?

Bản thảo

Cảm ơn vì những câu trả lời tuyệt vời, sự hiểu biết của tôi về LEFT OUTER THAM GIA bây giờ tốt hơn nhiều, tuy nhiên có ai có thể đề xuất một cách truy vấn này để tôi chỉ nhận được nhiều bản ghi như tồn tại trong bảng bên trái không?

Truy vấn này hoàn toàn là để tạo một báo cáo và các kết quả trùng lặp đơn giản chỉ là vấn đề gây nhầm lẫn.

/ Bản tin


5
Để "lấy càng nhiều bản ghi được trả lại như tồn tại trong bảng bên trái", bạn cần chỉ định hàng nào từ phía bên phải để chọn nếu có nhiều kết quả khớp.
AK

1
Làm thế nào để bạn xác định điều này? Tôi muốn trận đấu đầu tiên được trả lại.
Simon Cross

1
bạn phải xác định những gì có nghĩa là trận đấu đầu tiên. Bạn có muốn bản ghi sớm nhất, bản có id cao nhất hay không?
HLGEM

1
Nếu bạn khớp với khóa chính trong bảng bổ sung, tuyên bố của bạn là chính xác.
Ca ngợi thần thánh

Tôi thường sử dụng một tài nguyên như thế này như một bảng cheat khi xây dựng các truy vấn. Nếu liên kết đã chết, chỉ cần tham gia google sql ; chúng là sơ đồ Venn của các loại tham gia khác nhau.
Zimano

Câu trả lời:


190

LEFT OUTER THAM GIA sẽ trả về tất cả các bản ghi từ bảng LEFT được nối với bảng ĐÚNG nếu có thể.

Tuy nhiên, nếu có các trận đấu, nó vẫn sẽ trả về tất cả các hàng khớp, do đó, một hàng trong TRÁI khớp với hai hàng trong RIGHT sẽ trả về dưới dạng hai ROWS, giống như một THAM GIA VÀO.

EDIT: Đáp lại chỉnh sửa của bạn, tôi vừa có một cái nhìn sâu hơn về truy vấn của bạn và có vẻ như bạn chỉ đang trả lại dữ liệu từ bảng TRÁI. Do đó, nếu bạn chỉ muốn dữ liệu từ bảng TRÁI và bạn chỉ muốn một hàng được trả về cho mỗi hàng trong bảng TRÁI, thì bạn không cần phải thực hiện THAM GIA và chỉ có thể thực hiện CHỌN trực tiếp từ bảng TRÁI.


1
Lý do tham gia vào bảng bên phải là vì vậy tôi chỉ nhận được các bản ghi từ bên trái nơi có ít nhất một bản ghi trong bảng bên phải nhưng cảm ơn bạn rất nhiều vì đã giải thích.
Jay Wilde

125
Table1                Table2
_______               _________
1                      2
2                      2
3                      5
4                      6

SELECT Table1.Id, Table2.Id FROM Table1 LEFT OUTER JOIN Table2 ON Table1.Id=Table2.Id

Các kết quả:

1,null
2,2
2,2
3,null
4,null

1
Vì vậy, đơn giản, và rất mạnh mẽ.
kiradotee

39

Điều đó là không thể. Số lượng hồ sơ trong bảng bên trái là số lượng hồ sơ tối thiểu nó sẽ trả lại. Nếu bảng bên phải có hai bản ghi khớp với một bản ghi trong bảng bên trái, nó sẽ trả về hai bản ghi.


12

Đáp lại bài đăng của bạn, điều đó phụ thuộc vào những gì bạn muốn.

Bạn đang nhận được (có thể) nhiều hàng cho mỗi hàng trong bảng bên trái của mình vì có nhiều kết quả khớp cho điều kiện nối. Nếu bạn muốn tổng kết quả của mình có cùng số lượng hàng như ở phần bên trái của truy vấn, bạn cần đảm bảo các điều kiện nối của bạn gây ra kết quả trùng khớp 1-1.

Ngoài ra, tùy thuộc vào những gì bạn thực sự muốn, bạn có thể sử dụng các hàm tổng hợp (ví dụ: nếu bạn chỉ muốn một chuỗi từ phần bên phải, bạn có thể tạo một cột là một chuỗi được phân tách bằng dấu phẩy của kết quả bên phải cho hàng bên trái.

Nếu bạn chỉ nhìn vào 1 hoặc 2 cột từ phép nối ngoài, bạn có thể cân nhắc sử dụng truy vấn con vô hướng vì bạn sẽ được đảm bảo 1 kết quả.


4
Đây là một câu trả lời tốt vì nó đưa ra các đề xuất về cách chỉ trả lại các hàng từ bảng bên trái.
karns

9

Mỗi bản ghi từ bảng bên trái sẽ được trả lại nhiều lần vì có các bản ghi khớp trên bảng bên phải - ít nhất là 1, nhưng có thể dễ dàng nhiều hơn 1.


8

LEFT OUTER THAM GIA giống như INNER THAM GIA (tham gia bình thường) sẽ trả về nhiều kết quả cho mỗi hàng trong bảng bên trái như nhiều kết quả tìm thấy trong bảng bên phải. Do đó, bạn có thể có rất nhiều kết quả - lên tới N x M, trong đó N là số hàng trong bảng bên trái và M là số hàng trong bảng bên phải.

Đó là số lượng kết quả tối thiểu luôn được đảm bảo trong LEFT OUTER THAM GIA ít nhất là N.


1
Tôi bắt đầu nghĩ khi số lượng hàng bằng N x M và tình huống thực tế duy nhất xuất hiện trong đầu tôi là khi N hoặc M bằng 1. Bạn có đồng ý không?
BartoszMiller

2
Không, tôi không. Bạn không nên nghĩ về điều kiện tham gia là chỉ tham gia bình đẳng chính. Đó có thể là điều kiện tùy ý, ví dụ: phạm vi ngày, bất đẳng thức, v.v ... Hai trường hợp cực đoan: (a) N hàng không có một kết quả trùng khớp giữa các hàng M, sau đó để lại kết quả nối ngoài trong N hàng khớp với NULL. (b) mỗi N hàng khớp với tất cả các hàng M, kết quả là N x M hàng được đặt.
topchef

1
Bạn nói đúng, tôi đã nghĩ về việc tham gia chỉ về mặt bình đẳng chính. Tôi thích ví dụ của bạn từ "trường hợp b". Tôi tin rằng "mỗi hàng N khớp với tất cả các hàng M" là một công thức chung cho khi hàng N x M được trả về, điều này khá khó để hình dung khi chỉ nghĩ về đẳng thức chính.
BartoszMiller

7

Nó có thể là một mối quan hệ một đến nhiều giữa các bảng bên trái và bên phải?


6

Hãy chú ý nếu bạn có mệnh đề where trên bảng "bên phải" của truy vấn chứa liên kết ngoài bên trái ... Trong trường hợp bạn không có bản ghi ở bên phải thỏa mãn mệnh đề where, thì bản ghi tương ứng của 'bên trái 'bảng sẽ không xuất hiện trong kết quả truy vấn của bạn ....


1
Sau đó, bạn nên thêm điều kiện vào mệnh đề BẬT của THAM GIA TRÁI PHIẾU tương ứng.
Mik

6

Nếu bạn chỉ cần một hàng bất kỳ từ phía bên phải

SELECT SuspReason, SiteID FROM(
    SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER()
    OVER(PARTITION BY SUSP.Susp_Visits.SiteID) AS rn
    FROM SUSP.Susp_Visits
    LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
) AS t
WHERE rn=1

hoặc chỉ

SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits WHERE EXISTS(
    SELECT DATA.Dim_Member WHERE SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
)

1
Vì bạn không cung cấp DDL và DML, tôi đã không kiểm tra. Dù sao tôi nghĩ rằng EXISTS là những gì bạn muốn. Hãy thử điều này: CHỌN SuspRory, SiteID TỪ (CHỌN SUSP.Susp_Visits.SuspR Lý do THAM GIA DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum) NHƯ WHERE rn = 1
AK

2

Dường như có nhiều hàng trong bảng DATA.Dim_Member trên mỗi hàng SUSP.Susp_Visits.


2

nếu nhiều (x) hàng trong Dim_Member được liên kết với một hàng trong Susp_Visits, sẽ có x hàng trong bộ resul.

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.