24 题: “INNER JOIN”和“OUTER JOIN”有什么区别?

在...创建的问题 Wed, Feb 13, 2019 12:00 AM

LEFT JOIN,RIGHT JOINFULL JOIN如何适应?

    
4376
  1. 答案&评论&他们的参考文献只有一个实际上解释了维恩图如何表示运算符:圆形交叉区域表示A JOIN B中的行集。每个圆圈唯一的区域表示通过采用其获得的行集表没有参与A JOIN B的行,并且添加了对另一个表唯一的列,所有这些行都设置为NULL。 (而且大多数人给出A和B的圆圈模糊的虚假对应。)
    2014-10-18 20:24:59Z
  2. 已经提供了很多答案,但我还没有看到这个教程。如果您了解维恩图,这是一个很好的教程: blog.codinghorror .com /a-visual-explain-of-sql-joins 对我来说,它简洁到足以快速阅读,但仍然掌握整个概念并很好地处理所有情况。如果您不知道维恩图是什么 - 学习它们。花5到10分钟这样做,并且无论何时需要可视化使用集合和管理集合上的操作都会有所帮助。
    2017-05-09 09:04:59Z
  3. @ DanteTheSmith不,这与图中的问题相同。请参阅我上面的评论问题&以下博客文章:“杰夫在评论中拒绝了他的博客几页”。维恩图显示了集合中的元素。只是尝试确定这些图中的集合是什么以及元素是什么。集合不是表格,而元素不是它们的行。也可以连接任何两个表,所以PK和& FK是不重要的。所有虚假。你正在做成千上万的其他人做过的事 - 得到一个模糊的印象你(错误的)假设有意义。
    2017-05-18 05:57:51Z
  4. 有人可以参考时间序列索引数据来回答这个问题 - 当涉及时间戳时,内部和外部联接通常不适用于人类/维恩的意义不到一毫秒。
    2017-09-05 09:26:18Z
  5. 原始标题更清楚beng被问到什么(“不同的连接类型”可以指物理连接类型,例如哈希和合并)例如原始标题从视图数量来看,搜索引擎显然也很有效。我已将那些不需要的编辑回滚
    2019-02-13 08:14:08Z
  6. 醇>
    24答案                              24 跨度>                         

    假设您正在加入没有重复的列,这是一种非常常见的情况:

    • A和B的内连接给出A交叉B的结果,即维恩图交汇。

    • A和B的外连接给出A联合B的结果,即维恩图联合的外部部分。

    实施例强>

    假设您有两个表,每个表都有一个列,数据如下:

     
    A    B
    -    -
    1    3
    2    4
    3    5
    4    6
    

    注意(1,2)是A独有的,(3,4)是常见的,(5,6)是B独有的。

    内部联接

    使用任一等效查询的内部联接给出了两个表的交集,即它们共有的两行。

     
    select * from a INNER JOIN b on a.a = b.b;
    select a.*, b.*  from a,b where a.a = b.b;
    
    a | b
    --+--
    3 | 3
    4 | 4
    

    左外连接

    左外连接将给出A中的所有行,以及B中的所有公共行。

     
    select * from a LEFT OUTER JOIN b on a.a = b.b;
    select a.*, b.*  from a,b where a.a = b.b(+);
    
    a |  b
    --+-----
    1 | null
    2 | null
    3 |    3
    4 |    4
    

    右外连接

    右边er join将给出B中的所有行,以及A中的所有常见行。

     
    select * from a RIGHT OUTER JOIN b on a.a = b.b;
    select a.*, b.*  from a,b where a.a(+) = b.b;
    
    a    |  b
    -----+----
    3    |  3
    4    |  4
    null |  5
    null |  6
    

    全外联接

    完全外连接将为您提供A和B的并集,即A中的所有行和B中的所有行。如果A中的某些内容在B中没有对应的数据,则B部分为空,反之亦然。

     
    select * from a FULL OUTER JOIN b on a.a = b.b;
    
     a   |  b
    -----+-----
       1 | null
       2 | null
       3 |    3
       4 |    4
    null |    6
    null |    5
    
        
    5823
    2017-09-28 19:52:04Z
    1. 通过在表B中添加值为4的另一行来扩充示例是很好的。这将显示内部联接不必在行数上相等。
      2009-08-30 12:59:48Z
    2. 一个很好的解释,但是这句话: A和B的外连接给出了A联合B的结果,即维恩图联合的外部部分。没有准确措辞。除了下列之一外,外连接将给出A交叉B的结果:全部A(左连接),全部B(右连接)或全部A和全部B(完全连接)。只有这最后一个场景真的是一个联盟B.但仍然是一个写得很好的解释。
      2011-05-03 19:57:42Z
    3. 我是对的,FULL JOIN是FULL OUTER JOIN的别名,LEFT JOIN是LEFT OUTER JOIN的别名吗?
      2013-01-01 20:29:27Z
    4. 是非常好的解释。但是为什么在b列中值不是有序的?即它是6,5而不是5,6?
      2013-03-04 08:39:36Z
    5. @ Ameer,谢谢。 Join不保证订单,您需要添加ORDER BY子句。
      2013-03-05 00:28:16Z
    6. 醇>

    维恩图并没有真正为我做这件事。

    例如,它们没有显示交叉连接和内连接之间的任何区别,或者更一般地显示不同类型的连接谓词之间的任何区别,或提供一个框架来推断它们将如何操作。

    理解逻辑处理是无可替代的,无论如何都要相对简单。

    1. 想象一下交叉加入。
    2. 针对步骤1中的所有行评估on子句,将谓词计算结果保留为true
    3. (仅适用于外部联接)在步骤2中丢失的任何外部行中添加回来。
    4. 醇>

      (注意:在实践中,查询优化器可能会找到比上面的纯逻辑描述更有效的执行查询的方法,但最终结果必须相同)

      我将从完整外部联接的动画版本开始。进一步解释如下。


      解释

      来源表

      首先从CROSS JOIN(AKA笛卡尔积)开始。它没有ON子句,只返回两个表中的每个行组合。

      SELECT A.Colour,B.Colour from A CROSS JOIN B

      内部和外部联接具有“ON”子句谓词。

    • 内部联接。评估交叉联接结果中所有行的“ON”子句中的条件。如果为true则返回连接的行。否则丢弃它。
    • 左外连接。与内连接相同,然后对于左表中任何不匹配的行输出这些与右表列的NULL值。
    • 右外连接。与内连接相同,然后右表中任何与任何内容不匹配的行输出这些与左表列的NULL值。
    • 完全外部联接。与内部联接相同,然后保留左侧非匹配行,如左外部联接和右侧非匹配行,按照r外连接。

    一些例子

    SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour = B.Colour

    以上是经典的equi join。

    动画版

    SELECT A.Colour,B.Colour from A INNER JOIN B ON A.Colour NOT IN('Green','Blue')

    内连接条件不一定是相等条件,也不需要引用两个(甚至任何一个)表中的列。在交叉连接的每一行上评估A.Colour NOT IN ('Green','Blue')返回。

    SELECT A.Colour,B.Colour from A INNER JOIN B ON 1 = 1

    对于交叉连接结果中的所有行,连接条件的计算结果为true,因此这与交叉连接相同。我不会再重复16行的图片了。

    SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour

    外连接的逻辑评估方式与内连接的方式相同,只是如果左表中的一行(左连接)没有与右表中的任何行连接,则它将保留在结果中右侧列的值为NULL

    SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL

    这只是将前一个结果限制为仅返回B.Colour IS NULL所在的行。在这种特殊情况下,这些将是保留的行,因为它们在右侧表中没有匹配,并且查询返回表B中不匹配的单个红色行。这被称为反半连接。

    IS NULL测试选择一个不可为空的列或连接条件确保将排除任何NULL值以使此模式正常工作并避免仅返回碰巧发生的行时,这一点非常重要。除了未匹配的行之外,该列的值为NULL

    SELECT A.Colour,B.Colour from A RUST OUTER JOIN B ON A.Colour = B.Colour

    右外连接的作用类似于左外连接,除了它们保留右表中不匹配的行,null扩展左侧列。

    SELECT A.Colour,B.Colour from A FULL OUTER B B ON A.Colour = B.Colour

    完全外连接组合了左连接和右连接的行为,并保留左右表中不匹配的行。

    SELECT A.Colour,B.Colour from A Full OUTER JOIN B ON 1 = 0

    交叉连接中的任何行都不匹配1=0谓词。使用常规外部联接规则保留两侧的所有行,并在另一侧的表中使用NULL。

    SELECT COALESCE(A.Colour,B.Colour)AS颜色来自一个完整的外部连接B ON 1 = 0

    通过对前面的查询的一个小修改,可以模拟两个表中的UNION ALL

    SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour ='Green'

    请注意,WHERE子句(如果存在)在连接后逻辑运行。一个常见错误是执行左外连接,然后包含WHERE子句,右子表上的条件最终排除不匹配的行。以上结果是执行外连接...

    ...然后“Where”子句运行。 NULL= 'Green'的计算结果为true,因此外连接保留的行最终被丢弃(连同蓝色连接),有效地将连接转换回内连接。

    如果打算只包含B中的行,其中Color为绿色,而所有来自A的行都不包括正确的语法

    SELECT A.Colour,B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour AND B.Colour ='Green'

    SQL小提琴

    请参阅以下示例在SQLFiddle.com上直播

        
    623
    2018-08-03 07:59:59Z
    1. 我会说虽然这对我来说几乎和维恩图一样好,但我很欣赏人们的变化和学习方式不同而且这是一个非常好的呈现解释不同于我之前见过的,所以我支持@ypercube奖励积分。同样很好的工作解释了在JOIN子句和WHERE子句中放置附加条件的区别。感谢你,马丁史密斯。
      2014-12-20 04:48:36Z
    2. @ OldPro我认为维恩图是可以的,但他们对如何表示交叉连接或区分一种连接谓词这样做是默认的。作为equi从另一个加入。在交叉连接结果的每一行上评估连接谓词的心智模型,如果外部连接并最终评估哪里对我更有效,则在不匹配的行中添加回来。
      2014-12-20 11:05:32Z
    3. 维恩图适用于表示联盟和交叉点和差异,但不适用于联接。对于非常简单的连接,它们具有一些较小的教育价值,即连接条件在唯一列上的连接。
      2014-12-20 22:28:49Z
    4. @ Arth - 没错,你错了。 SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155 这是维恩的事情图表无法说明。
      2016-01-28 15:54:10Z
    5. @ MartinSmith哇,我同意,我完全错了!过去常常与一对一工作..感谢纠正。
      2016-01-28 15:57:18Z
    6. 醇>

    联接用于组合两个表中的数据,结果是一个新的临时表。连接是基于称为谓词的东西执行的,谓词指定了用于执行连接的条件。内连接和外连接之间的区别在于内连接将仅返回基于连接谓词实际匹配的行。 让我们考虑员工和位置表:

    内部加入: - 内连接通过基于连接谓词组合两个表( Employee Location )的列值来创建新的结果表。查询将 Employee 的每一行与 Location 的每一行进行比较,以查找满足join-predicate的所有行对。当通过匹配非NULL值来满足连接谓词时, Employee Location 的每对匹配行的列值将合并到结果行中。 以下是内部联接的SQL的样子:

     
    select  * from employee inner join location on employee.empID = location.empID
    OR
    select  * from employee, location where employee.empID = location.empID
    

    现在,运行SQL的结果如下:

    外部加入: - 外连接不要求两个连接表中的每个记录都具有匹配的记录。即使没有其他匹配记录,联接表也会保留每条记录。外连接进一步细分为左外连接和右外连接,具体取决于保留哪个表的行(左或右)。

    左外连接: - Employee Location 的左外连接(或简称左连接)的结果始终包含“左”表的所有记录( Employee ),即使连接条件在“右”表( Location )中找不到任何匹配的记录。 下面是使用上表中的左外连接的SQL:

     
    select  * from employee left outer join location on employee.empID = location.empID;
    //Use of outer keyword is optional
    

    现在,运行此SQL的结果如下:

    正确的外部加入: - 右外连接(或右连接)非常类似于左外连接,除了对表的处理进行了反转。 “右”表(位置)中的每一行都将至少出现在连接表中一次。如果“左”表( Employee )中没有匹配的行,则 Employee 中的列将显示为 Location 不匹配的记录。 这就是SQL的样子:

     
    select * from employee right outer join location  on employee.empID = location.empID;
    //Use of outer keyword is optional
    

    使用上面的表格,我们可以显示右外连接的结果集是什么样的:

    完整的外部联接: - 完全外连接或完全连接是通过在连接的结果中包含不匹配的行来保留不匹配的信息,使用完全外连接。它包括来自两个表的所有行,无论另一个表是否具有匹配值。

    图片来源

    MySQL 8.0参考手册 - 加入语法

    Oracle加入操作

        
    142
    2018-08-07 14:38:49Z

    内部加入

    仅检索匹配的行,即A intersect B

     
    SELECT *
    FROM dbo.Students S
    INNER JOIN dbo.Advisors A
        ON S.Advisor_ID = A.Advisor_ID
    

    左外连接

    从第一个表中选择所有记录,在第二个表中选择所有记录 与连接键匹配的表。

     
    SELECT *
    FROM dbo.Students S
    LEFT JOIN dbo.Advisors A
        ON S.Advisor_ID = A.Advisor_ID
    

    完全外部加入

    从第二个表中选择所有记录,并在第一个表中选择所有记录 与连接键匹配的表。

     
    SELECT *
    FROM dbo.Students S
    FULL JOIN dbo.Advisors A
        ON S.Advisor_ID = A.Advisor_ID
    

    参考

    121
    2014-07-21 15:38:32Z
    1. 工具的名称是什么?我发现它很有趣,因为它显示了行数和维恩图
      2014-01-27 12:23:03Z
    2. @ GrijeshChauhan Datamartist :)
      2014-01-27 12:25:31Z
    3. @ Trushar :(它不适用于Linux系统..
      2014-01-27 12:27:42Z
    4. @ GrijeshChauhan是的你可以尝试使用 wine来运行它
      2014-01-27 12:30:38Z
    5. 哦!是的我..我使用了SQLyog使用葡萄酒..还有 PlayOnLinux
      2014-01-27 12:32:59Z
    6. 醇>

    简单来说:

    内部联接仅检索匹配的行。

    外部联接从一个表和其他表中的所有行中检索匹配的行....结果取决于您使用的是哪一行:

    • :右表中匹配的行和左表中的所有行

    • 正确:左表中的匹配行和右表中的所有行或

    • 完整:所有表格中的所有行。

    • 是否匹配并不重要
    106
    2014-07-21 15:35:37Z
    1. @ nomen不是这个答案解决了它,但是INNER JOIN是一个交集,而FULL OUTER JOIN是相应的UNION 如果左边&右集/圆圈包含(分别)LEFT&行的行。正确加入。 PS这个答案不清楚输入与输出中的行。它将“在左/右表中”混淆为“在左/右有一个左/右部分”,它使用“匹配行”和“全部”来表示从其他表中行的行扩展为空行。
      2015-11-29 01:17:46Z
    2. 醇>

    如果在连接的另一侧(右侧)有匹配的记录,则内部联接仅显示行。

    (左)外连接显示左侧每条记录的行,即使连接的另一侧(右侧)没有匹配的行。如果没有匹配的行,则另一侧(右侧)的列将显示NULL。

        
    100
    2015-01-05 01:14:26Z

    内部联接要求联接表中存在具有相关ID的记录。

    即使右侧没有任何内容,外连接也会返回左侧的记录。

    例如,您有一个Orders和一个OrderDetails表。它们与“OrderID”相关联。

    订单强>

    • 订单ID
    • 客户名称

    订单明细强>

    • OrderDetailID
    • 订单ID
    • 产品名称
    • 数量
    • 价格

    请求

     
    SELECT Orders.OrderID, Orders.CustomerName
      FROM Orders 
     INNER JOIN OrderDetails
        ON Orders.OrderID = OrderDetails.OrderID
    

    只返回在OrderDetails表中也有内容的订单。

    如果您将其更改为OUTER LEFT JOIN

     
    SELECT Orders.OrderID, Orders.CustomerName
      FROM Orders 
      LEFT JOIN OrderDetails
        ON Orders.OrderID = OrderDetails.OrderID
    

    然后它将返回Orders表中的记录,即使它们没有OrderDetails记录。

    您可以使用它来查找没有任何OrderDetails的订单,通过添加像WHERE OrderDetails.OrderID IS NULL这样的where子句来指示可能的孤立订单。

        
    75
    2018-09-10 08:25:51Z
    1. 我很欣赏这个简单而现实的例子。我成功地将SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC等请求更改为SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL)。我不确定附加条件,它们混合得很好......
      2013-01-05 11:11:24Z
    2. 醇>

    简单来说:

    内部联接 - >从父表和子表中获取常用记录WHERE主表的主键与子表中的外键匹配。

    左连接 - >

    伪代码

     
    1.Take All records from left Table
    2.for(each record in right table,) {
        if(Records from left & right table matching on primary & foreign key){
           use their values as it is as result of join at the right side for 2nd table.
        } else {
           put value NULL values in that particular record as result of join at the right side for 2nd table.
        }
      }
    

    右连接:与左连接完全相反。将表的名称放在右连接右侧的LEFT JOIN中,得到与LEFT JOIN相同的输出。

    外部联接:显示两个表No matter what中的所有记录。如果Left表中的记录与Primary,Forieign键的右表不匹配,则使用NULL值作为join的结果。

    示例:

    现在让我们假设2个表

    1.employees , 2.phone_numbers_employees

     
    employees : id , name 
    
    phone_numbers_employees : id , phone_num , emp_id   
    

    这里,employees表是Master表,phone_numbers_employees是子表(它包含emp_id作为外键,连接employee.id所以它的子表。)

    内部联接

    获取2个表的记录仅因为员工表的主键(其ID)与子表phone_numbers_employees(emp_id)的外键匹配

    所以查询将是:

     
    SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
    

    这里只采用主键=外键上的匹配行,如上所述。作为连接结果,主键=外键上的非匹配行被跳过。

    左连接

    左连接保留左表的所有行,无论是否在右表上都有匹配的行。

     
    SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
    

    外部联接

     
    SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
    

    直观地看起来像是:

        
    62
    2015-02-19 05:11:56Z
    1. 结果与主要/唯一/候选键无关(做本身)&外键。可以而且应该在不参考它们的情况下描述baviour。计算交叉连接,然后滤除与ON条件不匹配的行;另外对于外连接行,过滤/不匹配的行由NULL扩展(每个LEFT /RIGHT /FULL并包含在内。
      2015-08-10 04:27:54Z
    2. 醇>

    使用 INNER JOIN 返回匹配的两个表中的所有行。即在结果表中,所有行和列都将具有值。

    OUTER JOIN 中,结果表可能包含空列。外联接可以是LEFTRIGHT

    LEFT OUTER JOIN 会返回第一个表中的所有行,即使第二个表中没有匹配项也是如此。

    RIGHT OUTER JOIN 会返回第二个表中的所有行,即使第一个表中没有匹配项也是如此。

        
    55
    2015-06-09 03:21:07Z

    的一个很好的解释

    这是所有类型连接的一个很好的图解说明

    来源: http://ssiddique.info/understanding-sql-加入功能于易于way.html

        
    54
    2016-10-18 18:48:59Z

    INNER JOIN要求在比较两个表时至少存在匹配。例如,表A和表B表示A 8 B(A交点B)。

    LEFT OUTER JOINLEFT JOIN是相同的。它给出了两个表中匹配的所有记录以及左表的所有可能性。

    同样,RIGHT OUTER JOINRIGHT JOIN是相同的。它给出了两个表中匹配的所有记录以及右表的所有可能性。

    FULL JOINLEFT OUTER JOINRIGHT OUTER JOIN的组合,没有重复。

        
    51
    2013-09-26 21:25:28Z

    答案在于每个人的意思,所以在结果中。

      

    注意:
      在SQLite中没有RIGHT OUTER JOINFULL OUTER JOIN
      而且在MySQL中也没有FULL OUTER JOIN

    我的回答基于注意

    当您有两个这样的表时:

     
    --[table1]               --[table2]
    id | name                id | name
    ---+-------              ---+-------
    1  | a1                  1  | a2
    2  | b1                  3  | b2
    

    CROSS JOIN /OUTER JOIN:
    您可以将所有这些表数据与CROSS JOIN,一样使用:

     
    SELECT * FROM table1, table2
    --[OR]
    SELECT * FROM table1 CROSS JOIN table2
    
    --[Results:]
    id | name | id | name 
    ---+------+----+------
    1  | a1   | 1  | a2
    1  | a1   | 3  | b2
    2  | b1   | 1  | a2
    2  | b1   | 3  | b2
    

    INNER JOIN:
    如果要根据table1.id = table2.id之类的关系为上述结果添加过滤器,可以使用INNER JOIN

     
    SELECT * FROM table1, table2 WHERE table1.id = table2.id
    --[OR]
    SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
    
    --[Results:]
    id | name | id | name 
    ---+------+----+------
    1  | a1   | 1  | a2
    

    LEFT [OUTER]加入:
    如果您希望在上述结果中拥有其中一个表的所有行 - 具有相同的关系 - 您可以使用LEFT JOIN
    (对于 RIGHT JOIN 只需更改表格的位置)

     
    SELECT * FROM table1, table2 WHERE table1.id = table2.id 
    UNION ALL
    SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
    --[OR]
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
    
    --[Results:]
    id | name | id   | name 
    ---+------+------+------
    1  | a1   | 1    | a2
    2  | b1   | Null | Null
    

    FULL OUTER JOIN:
    如果您还希望在结果中包含其他表的所有行,则可以使用FULL OUTER JOIN

     
    SELECT * FROM table1, table2 WHERE table1.id = table2.id
    UNION ALL
    SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
    UNION ALL
    SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
    --[OR] (recommended for SQLite)
    SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
    UNION ALL
    SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
    WHERE table1.id IS NULL
    --[OR]
    SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
    
    --[Results:]
    id   | name | id   | name 
    -----+------+------+------
    1    | a1   | 1    | a2
    2    | b1   | Null | Null
    Null | Null | 3    | b2
    

    嗯,根据您的需要,您可以选择满足您需求的每一个;)。

        
    39
    2017-09-12 08:50:33Z
    1. 您可以在笔记中添加MySQL中没有full outer join
      2015-06-14 13:34:13Z
    2. 醇>

    内部联接。

    联接正在组合两个表中的行。 内部联接尝试根据您在查询中指定的条件匹配两个表,并仅返回匹配的行。如果连接中第一个表中的一行与第二个表中的两个行匹配,则结果中将返回两行。如果第一个表中的某行与第二个表中的行不匹配,则不会返回该行;同样,如果第二个表中的某行与第一个表中的行不匹配,则不会返回。

    外部加入。

    左连接尝试查找第一个表中的行与第二个表中的行的匹配。如果找不到匹配项,它将返回第一个表中的列,并将第二个表中的列留空(null)。

        
    31
    2016-02-02 11:14:00Z

    在其他答案中,我没有看到关于性能和优化器的更多细节。

    有时很高兴知道只有INNER JOIN是关联的,这意味着优化器有最多的选择。它可以重新排序连接顺序,以便更快地保持相同的结果。优化器可以使用最多的连接模式。

    通常,尝试使用INNER JOIN而不是不同类型的连接是一种好习惯。 (当然,如果可以考虑预期的结果集。)

    这里有一些关于这种奇怪的联想行为的好例子和解释:

    25
    2017-05-23 12:34:48Z
    1. 使用一种类型的连接而不是另一种类型的连接可能不是“好习惯”。您使用哪种连接决定了您想要的数据。如果你使用另一个,那就错了。另外,在Oracle中至少这个答案是完全错误的。这听起来完全错误,你没有证据。你有证据吗?
      2014-12-26 08:51:00Z
    2. 1。我的意思是尝试使用。我看到很多人在没有任何充分理由的情况下到处使用LEFT OUTER加入。 (连接的列'不为空'。)在这些情况下,使用INNER连接肯定会更好。 2.我添加了一个更好地解释非关联行为的链接。
      2014-12-26 11:01:45Z
    3. 据我所知INNER JOIN在大多数情况下比LEFT JOIN慢,人们可以使用LEFT JOIN代替INNER JOIN,添加WHERE以删除意外的NULL结果;)。
      2015-05-13 03:01:51Z
    4. 这些评论让我有点不确定。为什么你认为INNER比较慢?
      2015-05-13 08:04:42Z
    5. 醇>

    INNER JOIN,LEFT/RIGHT OUTER JOIN的精确算法如下:

    1. 从第一张表中取出每一行:a
    2. 考虑旁边第二个表格中的所有行:(a, b[i])
    3. 针对每对评估ON ...条款:ON( a, b[i] ) = true/false?
      • 当条件评估为true时,返回组合行(a, b[i])
      • 当没有任何匹配到达第二个表的末尾时,这是一个Outer Join然后使用Null为其他表的所有列返回(虚拟)对:(a, Null)用于LEFT外连接或(Null, b)用于RIGHT外连接。这是为了确保第一个表的所有行都存在于最终结果中。
    4. 醇>

      注意: ON子句中指定的条件可以是任何内容,不需要使用主键(并且您不需要始终引用列中的列两个表)!例如:

    •  ... ON T1.title = T2.title AND T1.version < T2.version(=&gt;请参阅此帖子作为示例用法:仅选择列上具有最大值的行
    • ... ON T1.y IS NULL
    •  ... ON 1 = 0(就像样品一样)


    注意:左连接=左外连接,右连接=右外连接。

        
    22
    2018-10-11 14:16:16Z

    批评了备受喜爱的红色阴影维恩图,我认为发布自己的尝试是公平的。

    虽然@Martin Smith的答案在很长一段时间内是最好的,但他只显示每个表中的键列,而我认为理想情况下也应该显示非键列。

    我能在半小时内做到最好,我仍然认为它没有充分显示由于TableB中缺少关键值而存在空值,或者OUTER JOIN实际上是联合而不是连接:

        
    20
    2016-01-22 15:23:20Z
    1. 问题是要求INNER和OUTER连接之间的区别,但不一定是左外连接lol
      2016-01-22 19:32:48Z
    2. @ LearnByReading:我右边的图片是右外连接,即用TableA a LEFT OUTER JOIN TableB b替换TableB B RIGHT OUTER JOIN TableA a
      2019-04-29 07:58:14Z
    3. 醇>

    •  INNER JOIN最典型的连接两个或多个表。 它返回表ON主键和forignkey关系的数据匹配。
    •  OUTER JOININNER JOIN相同,但它还包含ResultSet上的NULL个数据。
      •  LEFT JOIN = INNER JOIN + 表的不匹配数据,右表有Null匹配。
      •  RIGHT JOIN = INNER JOIN + 表的不匹配数据,左表为Null匹配。
      •  FULL JOIN = INNER JOIN + 右侧和左侧表格上的数据不匹配,共有Null条匹配。
    • 当表引用数据本身知道为自联接时,自联接不是SQL中的关键字。使用INNER JOINOUTER JOIN,我们可以编写自联接查询。

    例如:

     
    SELECT * 
    FROM   tablea a 
           INNER JOIN tableb b 
                   ON a.primary_key = b.foreign_key 
           INNER JOIN tablec c 
                   ON b.primary_key = c.foreign_key 
    
        
    19
    2019-03-21 22:19:48Z

    最简单的定义

    内部联接:从两个表中返回匹配的记录

    完全外部联接:从两个表中返回匹配的和不匹配的记录,对于来自两个表的不匹配记录,返回null。

    左外连接:仅从左侧上的表格返回匹配和不匹配的记录。

    右外连接:仅从右侧上的表格返回匹配和不匹配的记录。

    在-短

    匹配+左侧不匹配+右侧不匹配= 完全外部加入

    匹配+左不匹配= 左外连接

    匹配+右无匹配= 右外连接

    匹配= 内部加入

        
    17
    2016-04-28 09:10:48Z
    1. 这很精彩,并解释了为什么连接不能按预期用于时间序列索引。一秒钟的时间戳是无与伦比的。
      2017-09-05 09:22:46Z
    2. @ yeliabsalohcin你没有在这里解释“按预期”或在你对这个问题的评论中“有用”。这只是一些无法解释的个人误解,你奇怪地期望别人拥有这种误解。如果你在阅读时把文字处理得很邋 - 错误解释清晰的写作和/或接受不清楚的写作 - 就像你在这里写作那样,你可能会有误解。事实上,这里的答案大多数都不清楚。错误。当输入列集不同时,“内部联接:从两个表返回匹配的记录”是错误的。它是尝试说出某种东西,但它不是。 (见我的回答。)
      2017-11-22 02:52:49Z
    3. 醇>

    简单来说,

    1. INNER JOIN或EQUI JOIN:返回仅匹配两个表中条件的结果集。

    2. OUTER JOIN:即使条件匹配与否,也返回两个表中所有值的结果集。

    3. LEFT JOIN:返回左表中所有值的结果集,只返回与右表中的条件匹配的行。

    4. RIGHT JOIN:返回右表中所有值的结果集,只返回与左表中的条件匹配的行。

    5. 完全加入:完全加入和全外加入相同。

        
    6
    2016-10-13 09:04:54Z

    1. 内部加入:也称为加入。它返回Left表中的行,右表只返回,如果匹配。否则,它返回零记录。

    示例:

     
    SELECT
      e1.emp_name,
      e2.emp_salary    
    FROM emp1 e1
    INNER JOIN emp2 e2
      ON e1.emp_id = e2.emp_id
    

    2. 完全外部加入:也称为完全加入。它返回Left表和右表中的所有行

    示例:

     
    SELECT
      e1.emp_name,
      e2.emp_salary    
    FROM emp1 e1
    FULL OUTER JOIN emp2 e2
      ON e1.emp_id = e2.emp_id
    

    3. 左外连接:或简称为左连接。它返回Left表中存在的所有行以及右表中的匹配行(如果有)。

    4. 右外连接:也称为右连接。它返回左表中的匹配行(如果有),以及Right表中的所有行。

    加入的优势

  7. 执行得更快。
  8. 4
    2017-07-28 04:17:49Z
    1. 这仅在表具有相同列集时才正确。 (它将内部联接与交叉和完全联接与联合混淆。)“匹配”也是未定义的。阅读我的其他评论。
      2017-07-24 13:02:37Z
    2. 醇>
    • 内部联接 - 使用任意等效查询的内部联接会给出两个的交集,即两个他们有共同的行。

    • 左外连接 - 左外连接将提供A中的所有行以及B中的所有常见行。

    • 全外连接 - 完整外连接将为您提供A和B的并集,即A中的所有行和B中的所有行如果A中的某些东西在B中没有相应的数据,则B部分为空,反之亦然

    3
    2016-06-23 13:55:57Z
    1. 这既错又不清楚。除非表格具有相同的列,否则加入。外连接没有来自A或B的行,除非它们具有相同的列,在这种情况下不添加空值。你想说点什么,但你不是在说。你没有正确或清楚地解释。
      2017-02-03 11:15:30Z
    2. @ philipxy:在您的对帐单上不同意Join is not an intersection unless the tables have the same columns否。您可以加入任何您想要的列,如果值匹配,它们将一起加入。
      2017-04-11 09:23:49Z
    3. 该评论与您的​​答案一样不清楚。 (我想你可能会想到这样的结果,结果的公共列的子行值集合是每个输入的公共列的子行值集的交集;但这不是你写的。你不清楚。)
      2017-04-11 14:24:05Z
    4. 醇>

    left join on(又名left outer join on)返回inner join onunion all个由空值扩展的不匹配的左表行。

    right join (on aka right outer join on)返回inner join onunion all个由空值扩展的不匹配的右表行。

    full join on(又名full outer join on)返回inner join onunion all个不匹配的左表行,由空值扩展union all个不匹配的右表行,由空值扩展。

    (SQL Standard 2006 SQL /Foundation 7.7语法规则1,一般规则1b,3 c&amp; d,5 b。)

    所以不要outer join,直到你知道inner join的基础是什么。


    找出 inner join行返回

    阅读我的评论那里有许多困惑和放大答案很差。

    然后在这里阅读我的评论了很多困惑&amp;答案很差。

        
    3
    2018-07-23 05:53:22Z
    1. 我确实已经阅读了很多评论。当你说“维恩图,正确解释时,可以代表内外连接”,你的意思是观察者或维恩图本身正确解释吗?如果是后者,请绘制它:)
      2019-04-24 16:08:07Z
    2. 我不确定你想说什么。我在谈论维恩图作为元素集的标准解释。 (因为某些图表的使用甚至不管理它。)“正确”的应用程序包括说明集合和/或元素是什么。见c在本页顶部有50个upvotes的内容与外部连接的维恩图。我将把我的一些评论编辑成这个问题。我不想在这篇文章中使用维恩图。
      2019-04-24 16:31:27Z
    3. 我也不想要维恩图!
      2019-04-25 15:52:29Z
    4. 我必须承认,尽管我在评论中快速措辞,因为SQL涉及行李和nulls和SQL文化没有通用术语来命名和区分相关概念,即使清楚地解释维恩图的元素如何以输出“行”为1:1,更不用说输入“行”也是非常重要的。或者内部或外部联接做什么,更不用说他们的区别了。 “值”可以包括或不包括NULL,“行”可以是值列表与表值或变量&amp;中的槽。 “=”可能是SQL“=”vs vs equality。
      2019-04-25 17:44:05Z
    5. 类似于我们的笛卡尔积 - 产品 - 关系 - 产品讨论,我怀疑维恩图对那些已经理解了它的人来说很有意义。连接类型之间的差异!
      2019-04-29 07:51:15Z
    6. 醇>

    内连接和外连接之间的区别如下:

    1. 内连接是基于匹配元组组合表的连接,而外连接是基于匹配和不匹配元组组合表的连接。
    2. 内部联接合并来自两个表的匹配行,其中省略了不匹配的行,而外部联接合并来自两个表的行,不匹配的行填充空值。
    3. 内连接就像交叉操作,而外连接就像一个联合操作。
    4. 内部联接是两种类型,而外部联接是三种类型。
    5. 内连接较慢,而外连接比内连接快。
    1
    2017-10-17 12:25:56Z

    考虑以下2个表:

    EMP 强>

     
    empid   name    dept_id salary
    1       Rob     1       100
    2       Mark    1       300
    3       John    2       100
    4       Mary    2       300
    5       Bill    3       700
    6       Jose    6       400
    

    系强>

     
    deptid  name
    1       IT
    2       Accounts
    3       Security
    4       HR
    5       R&D
    

    内部加入:

    在sql查询中大部分只是 JOIN 。它只返回表之间的匹配记录。

    找出所有员工及其部门名称:

     
    Select a.empid, a.name, b.name as dept_name
    FROM emp a
    JOIN department b
    ON a.dept_id = b.deptid
    ;
    
    empid   name    dept_name
    1       Rob     IT
    2       Mark    IT
    3       John    Accounts
    4       Mary    Accounts
    5       Bill    Security
    

    如上所示,Jose不会从输出中的 EMP 打印,因为它的dept_id 6在Department表中找不到匹配项。同样,HRR&D行不会从 Department 表打印,因为它们在Emp表中找不到匹配项。

    因此,INNER JOIN或只是JOIN,只返回匹配的行。

    LEFT JOIN:

    这将返回LEFT表中的所有记录,并仅返回RIGHT表中的匹配记录。

     
    Select a.empid, a.name, b.name as dept_name
    FROM emp a
    LEFT JOIN department b
    ON a.dept_id = b.deptid
    ;
    
    empid   name    dept_name
    1       Rob     IT
    2       Mark    IT
    3       John    Accounts
    4       Mary    Accounts
    5       Bill    Security
    6       Jose    
    

    因此,如果您观察到上述输出,则LEFT表(Emp)中的所有记录都将打印出来自RIGHT表的匹配记录。

    HRR&D行未从部门表打印,因为他们在dept_id上的Emp表中找不到匹配项。

    因此,LEFT JOIN返回Left表中的所有行,只返回RIGHT表中的行。

    还可以查看DEMO 此处

        
    0
    2018-11-25 15:04:40Z
    1. 这里没有任何内容清楚地描述了连接的作用。 (它也没有解决它们之间的“差异”,除了说它们是不同的。)这对于一个10年之久的问题的许多答案(很多高度提升)都没有增加 - 它是否“有用”?
      2018-11-27 01:19:10Z
    2. 醇>
来源放置 这里