SQL Server中左联接和右联接之间的区别


225

我知道SQL Server中的联接。

例如。有两个表Table1,Table2。

它们的表结构如下。

create table Table1 (id int, Name varchar (10))

create table Table2 (id int, Name varchar (10))

表1的数据如下:

    Id     Name     
    -------------
    1      A        
    2      B    

表2数据如下:

    Id     Name     
    -------------
    1      A        
    2      B 
    3      C

如果我同时执行下面提到的两个SQL语句,则两个输出将相同

select *
from Table1
  left join Table2 on Table1.id = Table2.id

select *
from Table2
  right join Table1 on Table1.id = Table2.id

请在上述SQL语句中说明左右联接之间的区别。

Answers:


73
Select * from Table1 left join Table2 ...

Select * from Table2 right join Table1 ...

确实是完全可以互换的。但是,请尝试Table2 left join Table1(或同一对Table1 right join Table2)进行区别。此查询应为您提供更多行,因为Table2包含ID在Table1中不存在的行。


17
那么,为什么我们RIGHT JOIN只要用Just就能达到任何期望的结果LEFT JOIN呢?:P
user1857492

1
@SilapAliyev这实际上是一个很好的问题。谁能回答?:D
伊恩·楚特

21
Select * from Table1 left join Table 2将返回表1的Select * from Table1 right join Table 2所有记录以及表2的同时记录。相反的将返回表2的所有记录和表1的同时记录。希望对您有所帮助。
Programador Adagal

3
如果您使用多于2个表,则使用右
联接

1
@MarkusMeskanen,您正在更改一个由7个单词组成的简单句子。当您的356行句子包含多个句子并且需要更改“左右”的逻辑时,您会想知道只用一个单词就可以更改它...
Programador Adagal

1014

Codeproject的图像说明了SQL连接的简单基础,该图像取自:http : //www.codeproject.com/KB/database/Visual_SQL_Joins.aspx SQL连接说明


64
那里没有太多的“细节”。实际应该归功于codeproject页面,而不是我。但是我当然不介意关注:-)
Daan Timmer

6
@Daan Timmer不,也一定要相信你!您重新包装并转售以满足特定的特定需求。零售商也这样做,并获得了数十亿美元的
收益

我认为我们可能在“外部不包括JOIN”的最后一个数字的where子句中要求使用“ AND”条件。我认为查询需要更新为SELECT <select_list> FROM Table_A A Full OUTER JOIN Table_B B ON A.Key = B.Key WHERE A.Key IS NULL和B.Key IS NULL
Vinsinraw

不需要@vinsinraw。因为条件已经覆盖了:JOIN Table_B b ON A.Key = B.Key。OR条件工作正常。
Daan Timmer

这是维恩图的常见滥用。圆A和B都不能代表台A&B,圆A是A LEFT JOIN B&cirlce B是右连接B.此外,它并不重要接通状态是与按键都无关紧要&何在不起作用每案件。请参阅本页面本节“ Re Venn图” 上的评论和答案。
philipxy

37

您要从中获取数据的表为“左”。
您要加入的表格为“ RIGHT”。
左联接:从左表中取出所有项目,并(仅)从右表中取出匹配的项目。
右联接:从右表中取出所有项目,并(仅)从左表中取出匹配的项目。
所以:

Select * from Table1 left join Table2 on Table1.id = Table2.id  

给出:

Id     Name       
-------------  
1      A          
2      B      

但:

Select * from Table1 right join Table2 on Table1.id = Table2.id

给出:

Id     Name       
-------------  
1      A          
2      B   
3      C  

您是右联接表,而表上的行较少,而表 又有更多行
,并且
再次,左联接表是,表上具有较少行的表,而表又是更多行,
请尝试:

 If Table1.Rows.Count > Table2.Rows.Count Then  
    ' Left Join  
 Else  
    ' Right Join  
 End If  

22

(内部)联接:返回两个表中具有匹配值的记录。

左(外)联接:从左表返回所有记录,并从右表返回匹配的记录。

右(外)联接:从右表返回所有记录,并从左表返回匹配的记录。

FULL(OUTER)JOIN:当左表或右表中存在匹配项时,返回所有记录

例如,假设我们有两个带有以下记录的表:

表A

id   firstname   lastname
___________________________
1     Ram         Thapa
2     sam         Koirala
3     abc         xyz
6    sruthy       abc

表B

id2   place
_____________
1      Nepal
2      USA
3      Lumbini
5      Kathmandu

内部联接

注意:它给出两个表的交集。

内部联接

句法

SELECT column_name FROM table1 INNER JOIN table2 ON table1.column_name = table2.column_name;

将其应用于示例表:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA INNER JOIN TableB ON TableA.id = TableB.id2;

结果将是:

firstName       lastName       Place
_____________________________________
  Ram         Thapa             Nepal
  sam         Koirala            USA
  abc         xyz              Lumbini

左加入

注意:将提供TableA中所有选定的行,以及TableB中所有常见的选定行。

左联接

SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name = table2.column_name;

将其应用于样品表

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA LEFT JOIN TableB ON TableA.id = TableB.id2;

结果将是:

firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        Null

正确加入

注意:将提供TableB中所有选定的行,以及TableA中所有常见的选定行。

正确加入

句法:

SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column_name = table2.column_name;

将其应用到您的Samole表中:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA RIGHT JOIN TableB ON TableA.id = TableB.id2;

结果将bw:

firstName   lastName     Place
______________________________
Ram         Thapa         Nepal
sam         Koirala       USA
abc         xyz           Lumbini
Null        Null          Kathmandu

完全加入

注意:与联合操作相同,它将返回两个表中的所有选定值。

完全加入

句法:

SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.column_name = table2.column_name;

将其应用到您的样品表中:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA FULL JOIN TableB ON TableA.id = TableB.id2;

结果将是:

firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        Null
 Null         Null      Kathmandu

一些事实

对于INNER加入,顺序无关紧要

对于(LEFT,RIGHT或FULL)OUTER加入,顺序很重要

w3schools查找更多


12
select fields 
from tableA --left
left join tableB --right
on tableA.key = tableB.key

from此示例中的表格位于tableA关系的左侧。

tableA <- tableB
[left]------[right]

因此,如果您想从左侧表格(tableA)中获取所有行,即使右侧表格(tableB)中没有匹配项,也可以使用“左侧联接”。

而且,如果您想从右侧表格(tableB)中获取所有行,即使左侧表格(tableA)中没有匹配项,也可以使用right join

因此,以下查询与上面使用的查询等效。

select fields
from tableB 
right join tableA on tableB.key = tableA.key

10

您似乎在问:“如果我可以重写RIGHT OUTER JOINusing LEFT OUTER JOIN语法,那为什么还要使用语法RIGHT OUTER JOIN呢?” 我认为这个问题的答案是,因为语言的设计者不想对用户施加这样的限制(而且我认为他们会受到批评),这将迫使用户更改表的顺序在FROM某些情况下,仅在更改子句类型时才能在子句中使用。


有时左右外部连接完全可以互换,对吗?
2013年

4
@Alex:确实左右外部联接始终是可互换的。
2014年

8

您的两个陈述是等效的。

大多数人只使用LEFT JOIN它,因为它看起来更直观,并且是通用语法-我认为并非所有RDBMS支持RIGHT JOIN


“我不认为所有RDBMS都支持RIGHT JOIN”-当然,并非所有RDBMS都支持SQL。但是,如果您暗示某些SQL产品支持LEFT但不支持,RIGHT请指出哪些产品。
2011年

10
@onedaywhen例如,SQLite 3未实现RIGHTFULL OUTER JOIN sqlite.org/omitted.html
Mac_Cain13 2012年

0

我觉得我们可能要求的最后一个数字的AND条件whereOuter Excluding JOIN以便获得的理想结果A Union B Minus A Interaction B。我觉得查询需要更新为

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL AND B.Key IS NULL

如果使用OR,那么我们将获得的所有结果A Union B


0

从表1中选择*从左连接Table1.id = Table2.id的Table2

在第一个查询中,Left join左侧table1右侧table2进行比较

其中将显示1的所有属性,而在表2中仅显示满足条件的那些属性。

从表2中选择*右联接Table1.id = Table2.id上的Table1

在第一个查询中,Right join右侧table1左侧table2进行比较

其中将显示1的所有属性,而在表2中仅显示满足条件的那些属性。

这两个查询会产生相同的结果,因为在查询表声明的顺序是不同的像你声明表1表2中的左,右分别在第一左连接的查询,同时也宣告表1表2中的左,右分别在第二右连接查询。

这就是为什么两个查询都得到相同结果的原因。因此,如果您想要不同的结果,则分别执行这两个查询,

从表1中选择*从左连接Table1.id = Table2.id的Table2

从表1中选择*右联接Table1.id = Table2.id上的Table2


0

Select * from Table1 t1 Left Join Table2 t2 on t1.id=t2.id 根据定义:Left Join从表1中选择所有用“ select”关键字提及的列,并从表2中选择与“ on”关键字之后的条件匹配的列。

同样,通过定义:“右连接”从表2中选择所有用“ select”关键字提及的列,并从表1中选择与“ on”关键字后面的条件匹配的列。

参考您的问题,将两个表中的id与需要在输出中引发的所有列进行比较。因此,ID 1和ID 2在两个表中都是通用的,因此结果是您将有四个列,其中IDname列分别来自第一表和第二张表。

*select * from Table1 left join Table2 on Table1.id = Table2.id

上面的表达式从表1和列中获取所有记录(行),从表1和表2中获取具有匹配ID的表2。

select * from Table2 right join Table1 on Table1.id = Table2.id**

与上述表达式类似,它从表1和列中获取所有记录(行),并从表1和表2中获取与表2中的ID匹配的ID。来自table1的内容)。

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.