为什么选择RIGHT JOIN而不是LEFT JOIN


18

如果我理解正确,每个RIGHT JOIN

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

可以表示为LEFT JOIN

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

我个人认为该声明的意图是:

  • 首先得到 Persons
  • 然后Persons根据需要展开/重复,以匹配Orders

最好用的顺序来表示,而Persons LEFT JOIN Orders不是用相反的顺序来表示Orders RIGHT JOIN Persons(因此我从不使用RIGHT JOIN)。

有什么情况下RIGHT JOIN首选a?或者,是否有任何用例RIGHT JOIN可以做一些不能做的事情LEFT JOIN


12
我想不起来我想要一个正确的加入的情况。我遇到过这样的情况,由于性能原因,查询的执行计划将左联接翻转为右联接。但是从纯粹的代码编写角度来看,不,我不记得曾经写过正确的联接。
布兰登

2
我不认为这是关于“解释,编写或调试代码”的问题。这是在问一问,为什么一种语言具有两种功能,它们显然具有相同的作用,它们之间是否确实存在差异,以及何时不推荐使用“非显而易见的”特性。
菲利普·肯德尔

1
不,左联接几乎总是能最简洁地捕获您的需求,并且更容易推理。在我的工作场所,实际上我们已经制定了防止右连接的标准,因为从来没有必要使用右连接(即,总是可以用相反的左连接代替它们)。
mgw854 '16

8
我已经重新设定接近表决的位置-这个问题在这里很热门,因为了解联接之间的差异会影响软件设计(数据库设计是软件设计的一部分,可能查询数据库的算法也是其中之一)。它也可能是Database Administrators上的话题,并且那里也可能有重复项。
Thomas Owens

1
我不确定您是否建议这样RIGHT JOIN做或更常见。如果那是您的前提,那是不正确的。我想不出我曾经见过在代码或示例中都使用过正确联接的时候。是JOINLEFT OUTER JOIN。在极少数情况下,您可能会看到FULL OUTER JOIN
JimmyJames

Answers:


12

这取决于您要满足的要求。

“给所有人及其相应命令”是不一样的 “我希望所有与他们相应的人在一起的订单”,尤其是当您要使用is null没有相应匹配项的行时。这就是我所谓的“优势表”,即无论联接另一侧没有相应的行,我都希望从中获取行的表。

查看这些图像,您会发现它们不相同:

在此处输入图片说明

图像来源是这篇出色的文章

但是您是对的,只要通过反转连接中表的顺序就可以满足这两个要求。

但是我想,对于习惯于从左到右书写的西方人来说,使用左联接而不是右联接更为自然,因为我们似乎希望联接与selected列方向相同或顺序相同。

因此,倾向于右连接的可能原因是,在您的文化中,您是从右向左书写(例如在阿拉伯语或希伯来语书写系统中),并且您倾向于这样思考,这意味着大脑中的文本信息可能从右向左流动。

一些语言学家认为您的语言会影响您的思维方式:https : //www.edge.org/conversation/lera_boroditsky-how-does-our-language-shape-the-way-we-think


1
我已经开始按照这些思路进行思考,但是我认为这是不正确的。我开始想象用希伯来语写SQL(我从未真正做过)。OK:右对齐,从右到左,自上而下。您仍将首先提及表A,然后提及表B。使用右联接,您将排除(尤其是在null情况下)首先提及的大部分或全部表。我认为人的思想往往首先主要的最重要的联系在一起。无论写入方向如何,都会发生这种情况。您可以将它们称为“ FIRST JOIN”和“ SECOND JOIN”,并且这种偏见仍然会发生。
Mike支持Monica

我提供了指向您在下面显示的图像的链接。
乔恩·雷诺

@Mike我不建议人们用阿拉伯语或希伯来语写SQL。只是您的母语取向可能是您偏爱右连接的原因。但这只是一种可能。我发现左联接更自然。
图兰斯·科尔多瓦

现在,我将图像的创建者归功于此。我已经在高清电视上使用了很多年,而且我不记得它来自哪里,
TulainsCórdova16年

我精通希伯来语,但我仍然LEFT JOIN更自然。
Zev Spitz

3

用右连接没有(我知道的)可以用左连接完成的任何事情。但是有时左连接的语法比较丑陋。假设您有以下表格:

Persons
ID | Name

Orders
ID | CustomerId | other unimportant stuff

SpecialOrderDetails
ID | OrderId | other stuff

假设您需要获取数据库中所有人员的列表以及他们具有特殊订单详细信息的所有订单(我们将说并非所有订单都具有特殊订单详细信息)。因此,通常您会从人员到订单进行左连接。但是,然后您必须加入特殊的订单详细信息。如果在此使用内部联接,则可以有效地使从人到订单的左联接变为内部联接。IE:这是您要执行的操作,但是不起作用(它将排除没有特殊订单的任何人):

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

所以您可以这样重写它:

--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

尚不完全清楚(假设没有评论),但确实可以。如果这不仅仅是一次性的操作(即某人将不得不回来并有一天要进行维护),那么使用正确的联接可能会使意图更清晰。

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

这更简洁明了(但仅当正在阅读的人理解正确的联接时)。请注意,这可以用左联接来编写,但是它需要嵌套联接(与右联接相比,人们对这种联接的了解可能更少)。

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

在这一点上,可以选择最清楚的内容以及大多数人会理解的内容(如果您不知道该语法称为嵌套联接,您是否会知道该语法?)

简而言之,您不一定严格要求正确的联接,但是它们可能使阅读更容易。


我想也许您只是右撇子。
罗伯特·哈维

我不理解为什么在这种情况下您不能编写多个左联接: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我是,但是我不确定它的用意是什么。
Becuzz

@ZevSpitz也许从我写的内容还不清楚,但是想法是,仅当存在特殊的订单明细记录时,才需要订单中的字段。仅在一对存在时才加入他们。
Becuzz

-1

我可以看到RIGHT JOIN用于复制/合并目的。假设我有两个表A和B。A在左边,B在右边。假设我想在这两个表之间复制数据以使其等效。

如果我想显示所有在A中但不在B中的数据,那将是LEFT联接。如果我想显示B中所有不在A中的数据,那么它将正确连接。

因此,有时在合并和复制数据以保持预期状态时,左和右会派上用场。

除此之外,我没有其他理由使用RIGHT联接,因为所有RIGHT联接都可以转换为LEFT联接,反之亦然,根据表的排序或可视化方式,所有LEFT联接都可以转换为RIGHT联接。因此,在其他情况下这将是一个优先事项。

这是一个很好的链接,用于可视化SQL连接。

http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins


-1

左联接不是右联接的对立面,请检查以下情况是否给出不同的结果

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

表b和c始终是内部连接的,但在第一个a中左连接到其他连接,在第二个a中右连接

左联接不返回任何行,而右联接返回一个行


这读起来更像是切线评论,请参阅如何回答
gna

-2

从来没有任何理由偏爱RIGHT JOIN,而且LEFT JOIN更清楚:

SELECT Persons。*,Orders。*从Persons LEFT JOIN上 Orders ON Persons.ID = Orders.PersonID

因为它使您可以立即查看正在查询的表。鉴于RIGHT JOIN

SELECT人。*订单。* FROM订单RIGHT JOIN人员 ON Orders.PersonID = Persons.ID

第一个表写在JOIN。之后。

根据我的经验,我从未见过RIGHT JOIN


1
这给问题增加了什么?问题不是有什么区别?; 问题是我为什么要使用RIGHT JOIN
Zev Spitz

@ZevSpitz您要求的理由是选择哪一个,我给您一个理由。哪个用例都没有关系,因为它取决于口味。
kirie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.