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

Difference between left join and right join in SQL Server

我知道SQL Server中的联接。

例如。有两张桌子,表1,表2。

它们的表结构如下。

1
2
3
CREATE TABLE Table1 (id INT, Name VARCHAR (10))

CREATE TABLE Table2 (id INT, Name VARCHAR (10))

表1数据如下:

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

表2数据如下:

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

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

1
2
3
4
5
6
7
SELECT *
FROM Table1
  LEFT JOIN Table2 ON Table1.id = Table2.id

SELECT *
FROM Table2
  RIGHT JOIN Table1 ON Table1.id = Table2.id

请在上面的SQL语句中解释左联接和右联接的区别。


codeproject有这个图片,它解释了SQL连接的简单基础,摘自:http://www.codeproject.com/kb/database/visual_sql_joins.aspxSQL joins explained


1
SELECT * FROM Table1 LEFT JOIN Table2 ...

1
SELECT * FROM Table2 RIGHT JOIN Table1 ...

确实是完全可互换的。但是,尝试Table2 left join Table1(或它的同一对,Table1 right join Table2)来观察区别。这个查询应该给您更多的行,因为表2包含一个ID在表1中不存在的行。


从中获取数据的表是"左"。您要加入的表是"正确的"。左联接:从左表中获取所有项,并(仅)从右表中获取匹配项。右联接:从右表中获取所有项,并(仅)从左表中获取匹配项。所以:

1
SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.id = Table2.id

给予:

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

但是:

1
SELECT * FROM Table1 RIGHT JOIN Table2 ON Table1.id = Table2.id

给予:

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

您正在正确地连接表,表中的行数越少,行数越多。和同样,左键联接表,表中的行数越少,行数越多。尝试:

1
2
3
4
5
 IF Table1.Rows.Count > Table2.Rows.Count THEN  
    ' Left Join  
 Else  
    '
RIGHT JOIN  
 END IF

1
2
3
4
SELECT FIELDS
FROM tableA --left
LEFT JOIN tableB --right
ON tableA.key = tableB.key

在本例中,FROM中的表tableA位于关系的左侧。

1
2
tableA <- tableB
[LEFT]------[right]

因此,如果要从左表(tableA中提取所有行,即使右表(tableB中没有匹配项),也要使用"左联接"。

如果要从右表(tableB中取出所有行,即使左表(tableA中没有匹配项),也要使用RIGHT JOIN

因此,下面的查询等价于上面使用的查询。

1
2
3
SELECT FIELDS
FROM tableB
RIGHT JOIN tableA ON tableB.key = tableA.key

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

左(外)联接:返回左表中的所有记录和右表中的匹配记录。

右(外)联接:返回右表中的所有记录以及左表中匹配的记录。

完全(外部)联接:当左表或右表中有匹配项时返回所有记录

例如,假设我们有两个表,其中包含以下记录:

Table A

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

Table B

1
2
3
4
5
6
id2   place
_____________
1      Nepal
2      USA
3      Lumbini
5      Kathmandu

内部连接

Note: It give the intersection of two table.

Inner Join

句法

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

将其应用于示例表:

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

结果将是:

1
2
3
4
5
firstName       lastName       Place
_____________________________________
  Ram         Thapa             Nepal
  sam         Koirala            USA
  abc         xyz              Lumbini

左连接

Note : will give all selected rows in TableA, plus any common selected rows in TableB.

氧化镁

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

将其应用于示例表中

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

结果将是:

1
2
3
4
5
6
firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        NULL

右连接

Note:will give all selected rows in TableB, plus any common selected rows in TableA.

氧化镁

语法:

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

在Samole表中应用它:

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

结果将为bw:

1
2
3
4
5
6
firstName   lastName     Place
______________________________
Ram         Thapa         Nepal
sam         Koirala       USA
abc         xyz           Lumbini
NULL        NULL          Kathmandu

完全联接

Note : It is same as union operation, it will return all selected values from both tables.

氧化镁

语法:

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

在您的示例表中应用它:

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

结果将是:

1
2
3
4
5
6
7
firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        NULL
 NULL         NULL      Kathmandu

Some facts

对于内部连接,顺序无关紧要

对于(左、右或全)外部联接,顺序很重要。

在W3学校了解更多信息


你好像在问,"如果我能用LEFT OUTER JOIN语法重写RIGHT OUTER JOIN,那为什么还要用RIGHT OUTER JOIN语法呢?"我认为这个问题的答案是,因为语言的设计者不想对用户设置这样的限制(我认为如果他们这样做的话,他们会受到批评),这将迫使用户在某些情况下更改FROM子句中表的顺序,而仅仅是更改连接类型。


你的两个陈述是等价的。

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


Select * from Table1 t1 Left Join Table2 t2 on t1.id=t2.id。按定义:左联接从表1中选择带有"select"关键字的所有列,从表2中选择与"on"关键字后面的条件匹配的列。

同样,根据定义:右联接从表2中选择带有"select"关键字的所有列,从表1中选择与"on"关键字后面的条件匹配的列。

参考您的问题,将两个表中的ID与输出中需要抛出的所有列进行比较。因此,IDS1和ID2在这两个表中都很常见,因此,您将从第一个表和第二个表中按顺序拥有四列,分别具有ID和名称列。

江户十一〔一〕号

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

埃多克斯1〔2〕

与上面的表达式类似,它从表1中获取所有记录(行),从表2中获取与表1和表2中的ID匹配的列。(请记住,这是一个正确的连接,因此将考虑来自表2而不是来自表1的所有列)。


选择*从表1table1.id=table2.id上的左联接table2

在第一个查询中,left join将左侧表table1与右侧表table2进行比较。

其中,将显示表1的所有属性,而在表2中,只显示条件为真的那些属性。

选择*从表2右连接table1上的table1.id=table2.id

在第一个查询中,右联接将右侧表table1与左侧表table2进行比较。

其中,将显示表1的所有属性,而在表2中,只显示条件为真的那些属性。

两个查询的结果相同,因为查询中的表声明顺序不同,就像在第一个左联接查询中分别声明左表1和右表2,在第二个右联接查询中分别声明右表1和左表2。

这就是为什么在两个查询中得到相同结果的原因。所以如果您想要不同的结果,那么分别执行这两个查询,

选择*从表1table1.id=table2.id上的左联接table2

选择*从表1右联接table1.id=table2.id上的table2


我觉得我们可能需要Outer Excluding JOIN最后一个数字的where条款中的AND条件,以便得到A Union B Minus A Interaction B所期望的结果。我觉得需要将查询更新到

1
2
3
4
5
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的所有结果。