Lý do thích RIGHT THAM GIA hơn TRÁI THAM GIA


18

Nếu tôi hiểu chính xác, mọi RIGHT JOIN:

SELECT Persons.*, Orders.*
FROM Orders
RIGHT JOIN Persons ON Orders.PersonID = Persons.ID

có thể được biểu thị như một LEFT JOIN:

SELECT Persons.*, Orders.*
FROM Persons
LEFT JOIN Orders ON Persons.ID = Orders.PersonID

Ý kiến ​​cá nhân của tôi là ý định của tuyên bố:

  • Đầu tiên nhận được Persons
  • Sau đó mở rộng / lặp lại Personskhi cần thiết để phù hợp vớiOrders

được thể hiện tốt hơn theo thứ tự Persons LEFT JOIN Ordershơn là theo thứ tự ngược lại Orders RIGHT JOIN Persons(và RIGHT JOINkết quả là tôi không bao giờ sử dụng ).

Có bất kỳ tình huống mà một RIGHT JOINđược ưa thích? Hoặc, có trường hợp sử dụng nào RIGHT JOINcó thể làm điều gì đó LEFT JOINkhông thể?


12
Tôi không thể nhớ lại một trường hợp mà tôi muốn tham gia đúng. Tôi đã có trường hợp kế hoạch thực hiện của một truy vấn lật một liên kết bên trái thành một tham gia bên phải vì lý do hiệu suất. Nhưng từ quan điểm viết mã thuần túy, không, tôi không nhớ mình đã từng viết một quyền tham gia.
Brandon

2
Tôi không thấy đây là một câu hỏi về "giải thích, viết hoặc gỡ lỗi mã". Đó là hỏi tại sao một ngôn ngữ có hai tính năng dường như làm cùng một điều, nếu thực sự có bất kỳ sự khác biệt nào giữa chúng và nếu không thì ngôn ngữ "không rõ ràng" sẽ được ưu tiên hơn.
Philip Kendall

1
Không, một tham gia bên trái hầu như luôn nắm bắt những gì bạn cần một cách cô đọng nhất và dễ lý luận hơn. Tại nơi làm việc của tôi, chúng tôi thực sự có một tiêu chuẩn để ngăn chặn việc tham gia phải vì không bao giờ có trường hợp cần thiết (nghĩa là chúng luôn có thể được thay thế bằng tham gia bên trái đối diện).
mgw854

8
Tôi đã đặt lại các phiếu bầu gần - câu hỏi này thuộc chủ đề ở đây, vì hiểu được sự khác biệt giữa các phép nối ảnh hưởng đến thiết kế phần mềm (thiết kế cơ sở dữ liệu là một phần của thiết kế phần mềm, cũng như các thuật toán có thể truy vấn cơ sở dữ liệu). Nó cũng có thể là chủ đề tại Quản trị viên Cơ sở dữ liệu và cũng có thể có một bản sao ở đó.
Thomas Owens

1
Tôi không chắc chắn nếu bạn đề xuất đó RIGHT JOINlà khuyến nghị hoặc phổ biến hơn. Nếu đó là tiền đề của bạn, nó không chính xác. Tôi không thể nghĩ về một thời gian tôi từng thấy tham gia đúng được sử dụng trong cả mã và trong các ví dụ. Đó là JOINhoặc LEFT OUTER JOIN. Trong những trường hợp hiếm hoi bạn có thể thấy a FULL OUTER JOIN.
JimmyJames

Câu trả lời:


12

Điều đó phụ thuộc vào yêu cầu bạn đang cố gắng thực hiện.

Không giống nhau khi nói: "đưa tất cả mọi người và các đơn đặt hàng tương ứng của họ" rằng "Tôi muốn tất cả các đơn đặt hàng với những người tương ứng của họ" , đặc biệt nếu bạn sẽ sử dụng is nullđể mang các hàng không có kết quả tương ứng. Đó là cái mà tôi gọi là "bảng chiếm ưu thế", đó là bảng tôi muốn tìm nạp các hàng từ bất kể không có hàng nào ở phía bên kia của phép nối.

Nhìn vào hình ảnh này và bạn sẽ nhận thấy chúng không giống nhau:

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

Nguồn hình ảnh là bài viết tuyệt vời này .

Nhưng bạn đúng ở chỗ cả hai yêu cầu đều có thể được thực hiện bằng cách tham gia chỉ đảo ngược thứ tự của các bảng trong phép nối.

Nhưng tôi đoán rằng đối với người phương tây đã quen viết từ trái sang phải thì việc sử dụng các liên kết bên trái trên các liên kết bên phải trở nên tự nhiên hơn , vì chúng ta thấy như thể chúng ta muốn các liên kết theo cùng hướng hoặc theo cùng thứ tự với các selectcột ed.

Vì vậy, một lý do có thể thích tham gia đúng là vì trong nền văn hóa của bạn, bạn viết từ phải sang trái (như trong hệ thống chữ viết tiếng Ả Rập hoặc tiếng Do Thái) và bạn có xu hướng nghĩ theo cách đó, có nghĩa là trong thông tin văn bản não của bạn chảy từ phải sang trái .

Một số nhà ngôn ngữ học nghĩ rằng ngôn ngữ của bạn ảnh hưởng đến cách suy nghĩ của bạn: https://www.edge.org/conversation/lera_boroditsky-how-does-our-lingu-shape-the-way-we-think


1
Tôi đã bắt đầu suy nghĩ theo những dòng này, nhưng tôi không nghĩ đó là chính xác. Tôi bắt đầu tưởng tượng việc viết SQL bằng tiếng Do Thái (điều mà tôi chưa bao giờ thực sự làm). OK: phải hợp lý, từ phải sang trái, từ trên xuống. Bạn vẫn sẽ đề cập đến bảng A trước rồi đến bảng B. Với một phép nối đúng, sau đó bạn sẽ loại trừ (đặc biệt là trong trường hợp null) hầu hết hoặc tất cả các bảng được đề cập trước. Tôi nghĩ rằng tâm trí con người có xu hướng liên kết đầu tiên với chínhquan trọng nhất . Điều này xảy ra bất kể hướng viết. Bạn có thể gọi chúng là "THAM GIA ĐẦU TIÊN" và "THAM GIA THỨ HAI" và sự thiên vị này vẫn sẽ xảy ra.
Mike hỗ trợ Monica

Tôi đã bao gồm một liên kết đến hình ảnh bạn đã hiển thị dưới đây.
Jon Raynor

@Mike Tôi không đề nghị mọi người viết SQL bằng tiếng Ả Rập hoặc hebrew. Chỉ là có lẽ định hướng của tiếng mẹ đẻ của bạn có thể là một lý do để bạn thích tham gia đúng. Nhưng đó chỉ là một khả năng. Tôi thấy trái tham gia tự nhiên hơn.
Tulains Córdova

Bây giờ tôi đã cung cấp tín dụng do cho người tạo ra hình ảnh. Tôi đã có nó trong nhiều năm ở độ phân giải HD và tôi không nhớ nó đến từ đâu,
Tulains Córdova

Tôi thông thạo tiếng Do Thái và tôi vẫn thấy LEFT JOINtự nhiên hơn.
Zev Spitz

3

Không có bất cứ điều gì (mà tôi biết) có thể được thực hiện với một tham gia bên phải mà không thể được thực hiện với một tham gia bên trái. Nhưng đôi khi cú pháp với các phép nối trái là xấu hơn. Giả sử bạn có các bảng sau:

Persons
ID | Name

Orders
ID | CustomerId | other unimportant stuff

SpecialOrderDetails
ID | OrderId | other stuff

Giả sử bạn cần có một danh sách tất cả những người trong cơ sở dữ liệu của bạn và bất kỳ đơn hàng nào họ có với chi tiết đơn hàng đặc biệt (chúng tôi sẽ nói rằng không phải tất cả các đơn hàng đều có chi tiết đơn hàng đặc biệt). Vì vậy, bạn thường sẽ làm một liên kết trái từ mọi người để đặt hàng. Nhưng sau đó bạn phải tham gia vào chi tiết đặt hàng đặc biệt. Nếu bạn sử dụng một tham gia bên trong ở đó, nó sẽ thực sự biến liên kết bên trái từ mọi người thành các đơn hàng thành một tham gia bên trong. IE: đây là những gì bạn muốn làm nhưng không hoạt động (nó sẽ loại trừ bất kỳ ai không có đơn hàng đặc biệt):

select p.*, o.*, d.*
from Persons p
left join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Vì vậy, bạn có thể viết lại nó như thế này:

--get all the people without a special order
select p.*, NULL, NULL, ... --NULLs placeholders for all the fields from OrderDetails and SpecialOrderDetails
from Persons p
left join Orders o on o.CustomerId = p.Id
left join SpecialOrderDetails d on d.OrderId = o.Id
where o.Id is null 

union

--get all the people with a special order
select p.*, o.*, d.*
from Persons p
inner join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Không chính xác rõ ràng (giả sử không có ý kiến), nhưng nó thực hiện công việc. Nếu đây là một cái gì đó nhiều hơn một lần (nghĩa là một cái gì đó mà ai đó sẽ phải quay lại và duy trì một ngày nào đó) bằng cách sử dụng một quyền tham gia đúng có thể làm cho nó rõ ràng hơn ý định là gì.

select p.*, o.*, d.*
from Orders o
inner join SpecialOrderDetails d on d.OrderId = o.Id
right join Persons p on p.Id = o.CustomerId

Đó là một chút ngắn gọn và rõ ràng hơn (nhưng chỉ khi bất cứ ai đang đọc nó hiểu đúng tham gia). Lưu ý rằng điều này có thể được viết bằng các phép nối trái, nhưng nó đòi hỏi một phép nối lồng nhau (điều mà ít người có thể quen thuộc hơn các phép nối phải).

select p.*, o.*, d.*
from Persons p
left join Orders o 
    inner join SpecialOrderDetails d on d.OrderId = o.Id
on o.CustomerId = p.Id

Tại thời điểm này, đó là một sự lựa chọn về những gì rõ ràng nhất và những gì hầu hết mọi người sẽ hiểu (bạn có biết làm thế nào để google cú pháp đó nếu bạn không biết nó được gọi là tham gia lồng nhau?).

Nói tóm lại, bạn không thực sự cần tham gia đúng, nhưng chúng có thể giúp đọc dễ dàng hơn.


Tôi nghĩ có lẽ bạn chỉ thuận tay phải.
Robert Harvey

Tôi không theo dõi lý do tại sao bạn không thể viết nhiều liên kết trái trong trường hợp này : SELECT p.*, o.*, d.* FROM Persons p LEFT JOIN Orders o ON o.CustomerID = p.ID LEFT JOIN SpecialOrders d ON o.Id = d.OrderID.
Zev Spitz

@RobertHarvey Tôi là, nhưng tôi không chắc chắn những gì thuận tay phải làm với nó.
Becuzz

@ZevSpitz Có thể không rõ ràng với những gì tôi đã viết, nhưng ý tưởng là bạn chỉ muốn các trường từ các đơn đặt hàng nếu có một bản ghi chi tiết đơn hàng đặc biệt tồn tại, tức là. chỉ tham gia với họ nếu cặp của họ tồn tại.
Becuzz

-1

Tôi có thể thấy RIGHT THAM GIA được sử dụng cho mục đích sao chép / hợp nhất. Giả sử tôi có hai bảng A và B. A ở bên trái và B ở bên phải. Giả sử tôi muốn sao chép dữ liệu giữa hai bảng này để làm cho chúng tương đương nhau.

Nếu tôi muốn hiển thị tất cả dữ liệu trong A nhưng không phải trong B thì đó sẽ là một tham gia TRÁI. Nếu tôi muốn hiển thị tất cả dữ liệu trong B không có trong A thì nó sẽ PHẢI tham gia.

Vì vậy, đôi khi TRÁI và PHẢI có ích khi hợp nhất và sao chép dữ liệu để giữ mọi thứ trong tương lai.

Ngoài ra, tôi không có lý do nào khác để sử dụng phép nối RIGHT vì tất cả các phép nối RIGHT có thể được chuyển đổi thành các phép nối LEFT hoặc ngược lại tất cả các phép nối LEFT có thể được chuyển đổi thành các phép nối RIGHT tùy thuộc vào cách các bảng được sắp xếp hoặc hiển thị. Vì vậy, nó sẽ là một vấn đề ưu tiên trong các trường hợp khác.

Đây là một liên kết đẹp để trực quan hóa Joins SQL.

http://www.codeproject.com/Articles/33052/Visual-Repftimeation-of-Query-Joins


-1

tham gia trái không phải là đối lập của tham gia phải, kiểm tra trường hợp sau đây cho kết quả khác nhau

select * from 
(select 1 as x  where 1=1) a left join 
(select 1 as x  where 1=0) b on a.x=b.x inner join 
(select 1 as x  where 1=1) c on b.x=c.x

select * from 
(select 1 as x where 1=1) c inner join 
(select 1 as x where 1=0) b on c.x=b.x right join 
(select 1 as x where 1=1) a on b.x=a.x

các bảng b anc c được liên kết bên trong nhưng trong lần đầu tiên a được nối với các bảng khác và ở lần thứ hai, a được nối phải

tham gia bên trái trả về không có hàng trong khi tham gia bên phải trả về một hàng


Điều này đọc giống như một bình luận tiếp tuyến, xem Cách trả lời
gnat

-2

Không bao giờ có bất kỳ lý do để thích RIGHT JOIN, và LEFT JOINrõ ràng hơn nhiều:

CHỌN Người. *, Đơn hàng. * TỪ Người TRÁI THAM GIA Đơn hàng TRÊN Người .ID = Đơn hàng.PersonID

vì nó cho phép bạn ngay lập tức xem bảng nào đang được truy vấn. Trong khi đó với RIGHT JOIN:

CHỌN Người. *, Đơn hàng. * TỪ Đơn hàng QUYỀN THAM GIA Người trên đơn đặt hàng.PersonID = Persons.ID

bảng đầu tiên được viết sau JOIN.

Theo kinh nghiệm của tôi, tôi chưa bao giờ thấy a RIGHT JOIN.


1
Điều này thêm gì vào câu hỏi? Câu hỏi không phải là sự khác biệt là gì? ; Câu hỏi là tại sao tôi nên sử dụng RIGHT JOIN? .
Zev Spitz

@ZevSpitz Bạn hỏi lý do thích cái nào hơn, tôi cho bạn một lý do. Trường hợp sử dụng nào không quan trọng vì đó là vấn đề của hương vị.
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.