左,右,外部和内部连接之间有什么区别?


562

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


60

3
这也取决于您的理解水平,对于像您这样的人,该文章不执行任何操作,但对于可能不完全了解加入的人,则非常清楚
SQLMenace

6
这是stackoverflow.com/questions/419375/sql-join-differences的重复副本,毫无疑问是其他...
cletus,2009年

1
这对我很有帮助...最简单的方法是制作测试表并使用它们。= P
daGrevis 2011年

Answers:


797

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

每个学生都可以分配到一个储物柜,因此表中有一LockerNumberStudent。一个单独的储物柜中可能有多个学生,但是特别是在学年开始时,您可能会有一些没有储物柜的新来学生和一些没有分配学生的储物柜。

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

INNER JOIN相当于“ 向我展示所有带储物柜的学生 ”。
任何没有储物柜的学生,或者没有学生的储物柜都将丢失。
返回70行

左外联接将是“ 向我显示所有学生,如果有的话,还带他们相应的储物柜 ”。
这可能是普通学生名单,或者可以用来识别没有储物柜的学生。
返回100行

正确的外部联接将是“ 显示所有储物柜,如果有的话,请分配给他们的学生 ”。
这可用于识别没有分配学生的储物柜,或拥有太多学生的储物柜。
返回80行(40个储物柜中的70个学生列表,外加10个没有学生的储物柜)

FULL OUTER JOIN会很愚蠢,可能用处不大。
例如“ 向我显示所有学生和所有储物柜,并在可以的地方进行匹配
返回110行(所有100名学生,包括那些没有储物柜的学生。还有10个没有学生的储物柜)

在这种情况下,CROSS JOIN也相当愚蠢。
它不使用lockernumberstudents表中的链接字段,因此,基本上,无论是否存在,您最终都会得到一个巨大的巨型列表,其中列出了每个可能的学生与储物柜配对。
返回5000行(100个学生x 50个储物柜)。可能有用(带有过滤功能)作为起点,将新学生与空的储物柜相匹配。


12
在您的示例中,CROSS连接对于创建储物柜分配非常有用:从所有可能的组合开始,然后使用其他条件从列表中过滤结果。
Joel Coehoorn

1
好答案。我认为交叉连接最常用于需要大量记录的情况下从几行生成测试数据。
Eli

6
当搜索孤立数据或比较同一数据集的不同版本时,FULL OUTER JOINS很有用。
Lara Dougan

3
交叉
联接

3
我认为您开始查询的方式会影响联接类型的结果。例如,SELECT * FROM students RIGHT OUTER JOIN lockers...将导致与结果不同的结果SELECT * FROM lockers RIGHT OUTER JOIN students...。很好的答案,但希望看到它带有完整的SQL查询进行更新
jbmilgrom

141

联接有三种基本类型:

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

通常,您会看到OUTER语法中省略了关键字。取而代之的是“ LEFT JOIN”,“ RIGHT JOIN”或“ FULL JOIN”。这样做是因为INNER和CROSS联接对于LEFT,RIGHT或FULL没有意义,因此它们本身足以明确表示OUTER联接。

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

  • INNER:您想返回“发票”表中的所有记录及其对应的“ InvoiceLines”。假设每张有效发票将至少有一行。
  • OUTER:您想返回特定发票的所有“ InvoiceLines”记录,以及它们对应的“ InventoryItem”记录。这是一家也出售服务的公司,因此并非所有InvoiceLines都具有IventoryItem。
  • CROSS:您有一个包含10行的数字表,每行具有从'0'到'9'的值。您想要创建一个要联接的日期范围表,以便最终获得该范围内每天的一条记录。通过将此表与自身交叉连接,可以创建所需的任意多个连续整数(假设您以10到1的幂开始,则每个联接将1加到指数上)。然后,使用DATEADD()函数将这些值添加到范围的基准日期。

1
真好 我通常只会在您只写“ JOIN”的情况下添加它,这意味着INNER JOIN。
matpop

47

只有4种:

  1. 内部连接:最常见的类型。对于在联接条件上匹配的每对输入行,都会产生一个输出行。
  2. 左外部联接:与内部联接相同,不同之处在于,如果在右侧表中找不到任何匹配行,则输出包含左侧表中值的行NULL,每个行对应右边表格中的值。这意味着左侧表中的每一行将在输出中至少出现一次。
  3. 右外部联接:与左外部联接相同,但表的角色相反。
  4. 完全外部联接:左右外部联接的组合。两个表中的每一行将至少出现在输出中一次。

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

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


1
完全外部联接和交叉联接(笛卡尔积)如何?
SQLMenace

完全等于两个外部连接
RussellH 2009年

25
当您拧紧内部联接时得到的是FULL,然后在这里问一个问题“为什么我要得到N ^ 2行而不是N”?然后每个人都会对您发怒。
Paul Tomblin,2009年

24

SQL JOINS的区别:

记住很简单:

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

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

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

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

在此处输入图片说明


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

9

在Wikipedia上签Join(SQL)

  • 内部联接-给定两个表,内部联接返回两个表中存在的所有行
  • 左/右(外部)联接-给定两个表返回联接的左表或右表中存在的所有行,并且当join子句匹配时返回另一侧的行,或者返回null那些专栏

  • 完整外部-给定两个表返回所有行,并且当左或右列都不存在时将返回null

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


6

使它更加可见可能会有所帮助。一个例子:

表格1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

表2:

ID_STUDENT LOCKER

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

4

LEFT JOINRIGHT JOIN是的类型OUTER JOIN

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


5
我不敢相信这个答案会有很多否决,同时又是如此不完整。
nbro

我认为这是对原始问题的更好答案。
罗素H

3

内部联接:仅显示行,两个表中都有数据时。

外连接(左/右):显示来自所有结果左/右与成对的排(表小号),如果它存在与否。


2

首先,您必须了解join的作用?我们连接多个表并从联接的表中获取特定结果。最简单的方法是交叉联接

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

左:它将返回左表中的所有记录以及右表中的匹配记录。

右:它将返回与左联接相反的方向。它将返回右表中的所有记录以及左表中的匹配记录。

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

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

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

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

谢谢

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.