题 INNER JOIN,LEFT JOIN,RIGHT JOIN和FULL JOIN之间有什么区别? [重复]


这个问题在这里已有答案:

有什么区别 INNER JOINLEFT JOINRIGHT JOIN 和 FULL JOIN  在 MySQL的


1207
2018-04-18 17:15


起源


tizag.com/mysqlTutorial/mysqljoins.php  tizag.com/mysqlTutorial/mysqlleftjoin.php - Brad
Jeff Attwood对维恩图的解释可能会为你做到。 SQL连接的可视化解释 - Cups
MySQL上不存在FULL外连接 - aleroot
我注意到答案都不是MySQL特有的 不 在某些领域有自己的语义。我也希望看到一个体面的写作。 - Lightness Races in Orbit
只有在2011年才能提出这样的问题,你现在就这样做,你就会立即投降,哈哈。 - Felipe Lopez


答案:


阅读这篇原创文章 代码项目 会帮助你很多: SQL连接的可视化表示

alt text

另请查看这篇文章: SQL SERVER - 更好的性能 - LEFT JOIN还是NOT IN?

找到原始的: MySQL中JOIN和OUTER JOIN的区别


2506
2018-05-31 13:29



这些照片不适合我。为什么右上图不是简单的 SELECT * FROM TableA;?为什么左上图不简单 SELECT * FROM TableB;?为什么中间的顶部图片没有 SELECT * FROM A INTERSECT SELECT * FROM B ?等等 - onedaywhen
我对整个概念有一个问题:那些是联合,交叉,除等等的视觉表示。它们没有投影的直观表示,因此不能加入。我认为当上下文加入时,它会比收益更加困惑。 - onedaywhen
不得不反对。我认为这些都是很好的可视化。您可以一眼看到使用某个连接时从两个表中选择的内容。 “onedaywhen”评论说“为什么不只是从表格中选择*”......好吧因为它是一个连接,需要两个表lol。 - Induster
SQL是一种从左到右读取的语言 - 是吗? :) - bjedrzejewski
该图有一个主要问题,即它完全忽略了半连接和连接之间的区别。那是: select a.* from a inner join b on a.id = b.id 与 select a.* from a where id in (select id from b)。这是因为SQL连接不是两个集合的交集 - 连接可以是一个 - >一个,一个 - >多个,或者多个 - >很多。因此,用维恩图表示实际上是不可能的:所有这些图表都显示“表格的哪一部分将参与连接”。在这种情况下 select a.* from a cross join b 应该与完全外连接具有相同的图表。 - ubanerjea


内部联接 获取基于外键在两个表之间共同的所有记录

LEFT JOIN 获取LEFT链接表中的所有记录,但如果您从RIGHT表中选择了一些列,如果没有相关记录,这些列将包含NULL

正确的加入 如上所述,但获取RIGHT表中的所有记录

完全加入 获取两个表中的所有记录,并将NULL放在相对表中不存在相关记录的列中


530
2018-04-18 20:28



这在技术上是不正确的:“INNER JOIN从一个表中获取第二个表中有一些相关条目的所有记录” - INNER JOIN不只是从一个表返回记录。 - nietaki
@nietaki“”INNER JOIN之间的区别是从一个表中获取所有记录,在第二个表中有一些相关条目“”和“INNER JOIN获取两个表之间共同的所有记录”?请注意,他从未说过只返回一个表中的记录。 - barlop
@barlop好的我看到评论者Nietaki认为在第一个声明中声称它只是从一个表中返回记录。后一个声明更加含糊不清,并没有解释内部连接的作用。所以这也是错的。 - barlop
当你说“INNER JOIN获取两个表之间通用的所有记录”时,它表明有一些测试可以查看两个记录是否相同。实际上它只是一个条件,例如/几乎总是,测试他们的领域是否平等。记录的其余部分不必相同,通常不会是'因为它们是相同的,所以首先加入它们是没有优势的。它加入了相应的记录.. - barlop
这里没有说明的是当你有多个相应的记录时会发生什么...在该字段中具有相同值的记录..在表A或表B或表A和B中。 - barlop


SQL JOIN子句用于组合来自两个或多个表的行,   基于它们之间的共同领域。

SQL中有不同类型的连接:

内部联接:当两个表中都匹配时返回行。

LEFT JOIN:返回左表中的所有行,即使右表中没有匹配项也是如此。

正确的加入:返回右表中的所有行,即使左表中没有匹配项也是如此。

完全加入:它结合了左外连接和右外连接的结果。

连接表将包含两个表中的所有记录,并填写任何一侧缺少匹配项的NULL。

自我加入:用于将表连接到自身,就像表是两个表一样,临时重命名SQL语句中的至少一个表。

CARTESIAN JOIN:返回两个或多个连接表中的记录集的笛卡尔积。

我们可以在详细信息中采用前四个连接:

我们有两个具有以下值的表。

表A

id  firstName                  lastName
.......................................
1   arun                        prasanth                 
2   ann                         antony                   
3   sruthy                      abc                      
6   new                         abc                                           

表B

id2 age Place
................
1   24  kerala
2   24  usa
3   25  ekm
5   24  chennai

.................................................. ..................

内部联接

注意 :它给出了两个表的交集,即它们在TableA和TableB中共有的行

句法

SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field;

将其应用于我们的样本表中:

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

结果将是

firstName       lastName       age  Place
..............................................
arun            prasanth        24  kerala
ann             antony          24  usa
sruthy          abc             25  ekm

LEFT JOIN

注意 :将给出TableA中的所有选定行,以及TableB中任何常用的选定行。

句法

SELECT table1.column1, table2.column2...
FROM table1
LEFT JOIN table2
ON table1.common_field = table2.common_field;

将其应用于我们的样本表中:

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

结果

firstName                   lastName                    age   Place
...............................................................................
arun                        prasanth                    24    kerala
ann                         antony                      24    usa
sruthy                      abc                         25    ekm
new                         abc                         NULL  NULL

正确的加入

注意 :将给出TableB中的所有选定行,以及TableA中任何常用的选定行。

句法

SELECT table1.column1, table2.column2...
FROM table1
RIGHT JOIN table2
ON table1.common_field = table2.common_field;

将其应用于我们的样本表中:

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

结果

firstName                   lastName                    age     Place
...............................................................................
arun                        prasanth                    24     kerala
ann                         antony                      24     usa
sruthy                      abc                         25     ekm
NULL                        NULL                        24     chennai

完全加入

注意 :它将返回两个表中的所有选定值。

句法

SELECT table1.column1, table2.column2...
FROM table1
FULL JOIN table2
ON table1.common_field = table2.common_field;

将其应用于我们的样本表中:

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

结果

firstName                   lastName                    age    Place
...............................................................................
arun                        prasanth                    24    kerala
ann                         antony                      24    usa
sruthy                      abc                         25    ekm
new                         abc                         NULL  NULL
NULL                        NULL                        24    chennai

有趣的事实

对于INNER加入,订单无关紧要

对于(LEFT,RIGHT或FULL)OUTER连接,顺序很重要

最好去检查一下 链接 它将为您提供有关加入订单的有趣详细信息


495
2018-02-25 12:40



full join 和a不是一回事 union。看到 stackoverflow.com/questions/905379/...        和 social.msdn.microsoft.com/Forums/sqlserver/en-US/... - iliketocode
查询不使用示例数据中的列。 - user2864740
@iliketocode感谢指出,回答编辑 - Arunprasanth K V
为什么订单对OUTER加入很重要?你的意思是性能与查询优化器?结果集是相同的。 - Andrii Rubtsov