INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有啥区别? [复制]

Posted

技术标签:

【中文标题】INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有啥区别? [复制]【英文标题】:What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN? [duplicate]INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别? [复制] 【发布时间】:2011-04-18 17:15:24 【问题描述】:

INNER JOINLEFT JOINRIGHT JOINFULL JOIN 有什么区别 在 mysql

【问题讨论】:

tizag.com/mysqlTutorial/mysqljoins.phptizag.com/mysqlTutorial/mysqlleftjoin.php Jeff Attwood 以维恩图为特色的解释可能对你有用。 A Visual Explanation of SQL Joins FULL external JOIN 在 MySQL 上不存在 我注意到没有一个答案是特定于 MySQL 的,它确实在某些领域有自己的语义。我也想看一篇像样的文章。 @Cups Atwood 在其 cmets 中否认了该帖子。维恩图在这个主题上大多被滥用并且无法完全解释。在 PranayRana 的(可怕的)答案中查看我的 cmets,并在重复链接中查看。 【参考方案1】:

阅读关于代码项目的这篇原创文章会对您有很大帮助:Visual Representation of SQL Joins。

另请查看此帖子:SQL SERVER – Better Performance – LEFT JOIN or NOT IN?。

在Difference between JOIN and OUTER JOIN in MySQL找到原始的。

【讨论】:

这些图片不适合我。为什么右上角的图片不是简单的SELECT * FROM TableA;?为什么左上图不是简单的SELECT * FROM TableB;?为什么顶部中间的图片不是SELECT * FROM A INTERSECT SELECT * FROM B?等 我对整个概念有疑问:这些是联合、相交、除外等的视觉表示。它们没有投影的视觉表示,因此不能是连接。我认为当上下文加入时,它会混淆而不是好处。 不得不不同意。我认为这些都是很好的可视化。一目了然,您可以看到使用某个联接时将从两个表中选择什么。 “onedaywhen”评论道“为什么不直接说 select * from table a”.... 好吧,因为它是一个连接,需要两个表,哈哈。 SQL 是一种从左到右阅读的语言 - 是吗? :) 这个图有一个主要问题,就是它完全忽略了半连接和连接的区别。即:select a.* from a inner join b on a.id = b.idselect a.* from a where id in (select id from b)。这是因为 SQL 连接不是两个集合的交集——连接可以是 one->one、one->many 或 many->many。所以实际上不可能用维恩图来表示:这个图所做的只是告诉你“表的哪一部分将参与连接”。在这种情况下,select a.* from a cross join b 应该与完全外连接具有相同的图表。【参考方案2】:

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

SQL 中有不同类型的连接可用:

INNER JOIN:当两个表都匹配时返回行。

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

RIGHT JOIN:返回右表中的所有行,即使左表中没有匹配项。

FULL JOIN:结合左右外连接的结果。

连接的表将包含两个表中的所有记录,并为两边缺失的匹配项填写 NULL。

SELF JOIN:将一个表连接到自身,就好像该表是两个表一样,在 SQL 语句中临时重命名至少一个表。

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

我们可以在 Details 中获取前四个连接:

我们有两个表,它们的值如下。

表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

左连接

注意:给出 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 联接,顺序很重要。

最好去看看这个Link,它会给你关于加入顺序的有趣细节。

【讨论】:

full joinunion 不同。见***.com/questions/905379/… 和social.msdn.microsoft.com/Forums/sqlserver/en-US/…【参考方案3】:

INNER JOIN 根据提供的 ON 子句获取两个表之间共有的所有记录。

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

RIGHT JOIN和上面一样,只是获取RIGHT表中的所有记录。

FULL JOIN 从两个表中获取所有记录,并将 NULL 放在对面表中不存在相关记录的列中。

【讨论】:

这在技术上是不正确的:“INNER JOIN 从一个表中获取所有记录,这些记录在第二个表中有一些相关条目” - INNER JOIN 不只是从一个表中返回记录。

以上是关于INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

SQL中left join on 、right join on、inner join on之间的区别

关于SQL 查询效率问题 left join 改成 inner join union

外连接(left join、full join、right join)与内连接(inner join)的区别

inner join left join right join 和full join的区别

MySQL left join right join inner join

left join right inner join 区别