左、右、外连接和内连接有啥区别? [复制]

Posted

技术标签:

【中文标题】左、右、外连接和内连接有啥区别? [复制]【英文标题】:What is the difference between Left, Right, Outer and Inner Joins? [duplicate]左、右、外连接和内连接有什么区别? [复制] 【发布时间】:2010-10-01 16:08:45 【问题描述】:

我想知道如何区分所有这些不同的连接...

【问题讨论】:

来自编码恐怖A Visual Explanation of SQL Joins 也取决于你的理解水平,对于像你这样的人来说,这篇文章除了对可能不完全理解的人来说什么都不会加入它很清楚 这对我帮助很大...最简单的方法是制作测试表并与它们一起玩。 =P browse-tutorials.com/tutorial/mysql-joins The Coding Horror blog using Venn diagrams linked in the high upvoted 1st comment here被其作者后来在其cmets中否定。维恩图在讨论外连接和内连接时具有误导性和误用。在我在第一次评论中给出的重复链接中查看我的 cmets。 【参考方案1】:

只有4种:

    内连接:最常见的类型。为在连接条件上匹配的每对输入行生成一个输出行。 左外连接:与内连接相同,不同之处在于如果右侧表中没有找到匹配行的任何行,则输出包含该表中的值的行在左侧,NULL 对应右侧表格中的每个值。这意味着左侧表格中的每一行将在输出中至少出现一次。 右外连接:与左外连接相同,只是表的角色颠倒了。 全外连接:左右外连接的组合。两个表中的每一行都会在输出中至少出现一次。

“交叉连接”或“笛卡尔连接”只是没有指定连接条件的内部连接,导致输出所有行对。

感谢 RusselH 指出 FULL 连接,我省略了。

【讨论】:

全外连接和交叉连接(笛卡尔积)怎么样? full 真的相当于两个外连接 FULL 是你搞砸内部连接时得到的结果,然后你在这里问一个问题“为什么我得到 N^2 行而不是 N”?然后每个人都会对你发火。【参考方案2】:

LEFT JOINRIGHT JOINOUTER JOINs 的类型。

INNER JOIN 是默认值 -- 两个表中的行必须匹配连接条件。

【讨论】:

我无法相信这个答案怎么会有这么多的赞成票,同时又如此不完整。 我认为这是对原始问题的更好回答。【参考方案3】:

查看Join (SQL) on Wikipedia

内连接 - 给定两个表,内连接返回两个表中存在的所有行

左/右(外)连接 - 给定两个表返回存在于连接的左表或右表中的所有行,加上当连接子句匹配时将返回另一侧的行否则这些列将返回 null

Full Outer - 给定两个表返回所有行,当左列或右列不存在时将返回空值

交叉连接 - 笛卡尔连接,如果不小心使用会很危险

【讨论】:

【参考方案4】:

简单示例:假设您有一个Students 表和一个Lockers 表。在 SQL 中,您在连接中指定的第一个表 StudentsLEFT 表,第二个表 LockersRIGHT 表。

每个学生都可以分配到一个储物柜,所以Student 表中有一个LockerNumber 列。一个储物柜中可能有多个学生,但尤其是在学年开始时,您可能会有一些没有储物柜的新生和一些没有分配学生的储物柜。

就本示例而言,假设您有 100 名学生,其中 70 名学生有储物柜。您总共有 50 个储物柜,其中 40 个储物柜至少有 1 个学生,10 个储物柜没有学生。

INNER JOIN 相当于“告诉我所有带储物柜的学生”。 任何没有储物柜的学生,或没有学生的任何储物柜都丢失了。返回 70 行

LEFT OUTER JOIN 将是“向我展示所有学生,如果他们有相应的储物柜,请带上他们的储物柜”。 这可能是一个普通的学生名单,或者可以用来识别没有储物柜的学生。 返回 100 行

RIGHT OUTER JOIN 将是“显示所有储物柜,以及分配给它们的学生(如果有的话)”。 这可用于识别没有分配学生的储物柜,或有太多学生的储物柜。 返回 80 行(40 个储物柜中的 70 名学生的列表,加上没有学生的 10 个储物柜)

FULL OUTER JOIN 会很傻,可能没什么用处。 类似“显示所有学生和所有储物柜,并在可以匹配的位置返回 110 行(所有 100 名学生,包括没有储物柜的学生。另外没有学生的 10 个储物柜)

CROSS JOIN 在这种情况下也相当愚蠢。 它不使用学生表中链接的lockernumber 字段,因此您基本上最终会得到一个包含所有可能的学生到-储物柜配对,无论它是否真的存在。返回 5000 行(100 个学生 x 50 个储物柜)。作为一个起点,将新学生与空储物柜匹配起来可能很有用(通过过滤)。

【讨论】:

使用您的示例,CROSS join 将作为创建储物柜分配的起点非常有用:从所有可能的组合开始,然后使用其他条件从列表中过滤结果。 不错的答案。我相信当您需要大量记录时,Cross Join 最常用于从几行生成测试数据。 FULL OUTER JOINS 在搜索孤立数据或比较同一数据集的不同版本时非常有用。 交叉加入又名笛卡尔积 我认为您开始查询的方式会影响连接类型的结果。例如,SELECT * FROM students RIGHT OUTER JOIN lockers... 将产生与SELECT * FROM lockers RIGHT OUTER JOIN students... 不同的结果。很好的答案,但希望看到它更新完整的SQL 查询【参考方案5】:

有三种基本的连接类型:

INNER join 比较两个表,只返回匹配的结果。当第一个表中的记录与第二个表中的多个结果匹配时,它们会重复。 INNER 联接往往会使结果集更小,但由于记录可以重复,因此不能保证这一点。 CROSS join 比较两个表并返回两个表中所有可能的行组合。您可以从这种连接中获得很多甚至可能没有意义的结果,因此请谨慎使用。 OUTER join 比较两个表并在匹配可用时返回数据,否则返回 NULL 值。与 INNER 连接一样,当它匹配另一张表中的多条记录时,这将复制一张表中的行。 OUTER 联接倾向于使结果集更大,因为它们本身不会从集中删除任何记录。您还必须限定 OUTER 连接以确定何时何地添加 NULL 值: LEFT 表示无论如何保留第一个表中的所有记录,并在第二个表不匹配时插入 NULL 值。 RIGHT 表示相反的意思:无论如何保留第二张表中的所有记录,并在第一张表不匹配时插入 NULL 值。 FULL 表示保留两个表中的所有记录,如果不匹配,则在任一表中插入 NULL 值。

您经常会看到语法中省略了OUTER 关键字。相反,它将只是“LEFT JOIN”、“RIGHT JOIN”或“FULL JOIN”。这样做是因为 INNER 和 CROSS 连接对于 LEFT、RIGHT 或 FULL 没有任何意义,因此它们本身就足以明确指示 OUTER 连接。

以下是您可能希望使用每种类型的示例:

INNER:您希望从“Invoice”表中返回所有记录,以及它们对应的“InvoiceLines”。这假定每张有效的发票都至少有一行。 OUTER:您想要返回特定发票的所有“InvoiceLines”记录,以及它们对应的“InventoryItem”记录。这是一家还销售服务的企业,因此并非所有 InvoiceLines 都有 IventoryItem。 CROSS:您有一个包含 10 行的数字表,每行包含值 '0' 到 '9'。您想创建一个日期范围表来加入,以便在该范围内的每一天都有一条记录。通过重复将此表与自身交叉连接,您可以根据需要创建任意数量的连续整数(假设您从 10 的 1 次方开始,每个连接都会将 1 添加到指数)。然后使用 DATEADD() 函数将这些值添加到该范围的基准日期。

【讨论】:

不错。如果你只写“JOIN”,我只会添加它,这意味着 INNER JOIN。【参考方案6】:

内连接:只显示行,当它有来自两个表的数据时。

外连接(左/右):显示左/右表的所有结果与配对行(s),如果它存在

【讨论】:

【参考方案7】:

让它更显眼可能会有所帮助。一个例子:

表 1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

表 2:

ID_STUDENT 储物柜

3               l1
4               l2
5               l3

当我做的时候我得到了什么:

-Inner join of Table 1 and Table 2: 

    - Inner join returns both tables merged only when the key 
      (ID_STUDENT) exists in both tables

    ID_STUDENT       STUDENT_NAME      LOCKER   

        3               Eduardo          l1
        4               Luiz             l2

-Left join of Table 1 and Table 2:

    - Left join merges both tables with all records form table 1, in 
      other words, there might be non-populated fields from table 2

    ID_ESTUDANTE    NOME_ESTUDANTE     LOCKER   

        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2

-Right join of table 1 and table 2:

    - Right join merges both tables with all records from table 2, in 
      other words, there might be non-populated fields from table 1

    ID_STUDENT        STUDENT_NAME     LOCKER   

        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

-Outter join of table 1 and table 2:

    - Returns all records from both tables, in other words, there
      might be non-populated fields either from table 1 or 2.

    ID_STUDENT        STUDENT_NAME     LOCKER   
        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

【讨论】:

【参考方案8】:

首先你要明白join是做什么的?我们连接多个表并从连接的表中获取特定结果。最简单的方法是cross join

假设 tableA 有两列 A 和 B。而 tableB 有三列 C 和 D。 如果我们应用交叉连接,它会产生很多无意义的行。然后我们必须使用主键进行匹配才能获取实际数据。

左:会返回左表的所有记录和右表的匹配记录。

右:它将与左连接相反。它将返回右表中的所有记录和左表中的匹配记录。

内:这就像十字路口。它将只返回两个表中匹配的记录。

外:这就像联合。它将返回两个表中的所有可用记录。

有时我们不需要所有数据,而且我们应该只需要常用数据或记录。我们可以使用这些连接方法轻松获得它。记住左右连接也是外连接。

您可以使用交叉连接获取所有记录。但是当涉及到数百万条记录时,它可能会很昂贵。因此,使用左、右、内或外连接使其变得简单。

谢谢

【讨论】:

【参考方案9】:

SQL JOINS 区别:

很容易记住:

INNER JOIN 只显示两个表共有的记录。

OUTER JOIN两个表的所有内容无论是否匹配都会合并在一起。

LEFT JOINLEFT OUTER JOIN 相同 - (从第一个(最左边的)表中选择与右表记录匹配的记录。)

RIGHT JOINRIGHT OUTER JOIN 相同 - (从第二个(最右侧)表中选择与左表记录匹配的记录。)

【讨论】:

有一种正确且相关的方式来标记维恩图圈,但这不是。圆圈不是输入表。结果行也不是输入行,因此您的描述在那里是错误的。这也不清楚——你没有解释“两者共同”、“匹配”、“合并”。

以上是关于左、右、外连接和内连接有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

SQL中有几种连接?有啥区别?(左连右连内连和外连?)

SQL中的左连接与右连接,内连接有啥区别

MySQL连接查询 内连接和外连接的区别

MySQL 的内连接、左连接、右连接有啥区别?

左连接和左外连接有啥区别? [复制]

SQL内连接与外连接的区别