580

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

4

9 回答 9

821

简单示例:假设您有一张Students桌子和一张Lockers桌子。在 SQL 中,您在连接中指定的第一个表Students, 是LEFT表,第二个表Lockers, 是RIGHT表。

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

为了这个例子,假设你有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 个储物柜)。可能有用(通过过滤)作为将新学生与空储物柜匹配的起点。

于 2009-01-15T19:18:49.527 回答
149

有三种基本的连接类型:

  • INNERjoin 比较两个表,并且只返回存在匹配的结果。当第一个表中的记录与第二个表中的多个结果匹配时,它们会重复。INNER 连接倾向于使结果集更小,但由于记录可以重复,这不能保证。
  • CROSSjoin 比较两个表并返回两个表中所有可能的行组合。您可以从这种连接中获得很多甚至可能没有意义的结果,因此请谨慎使用。
  • OUTERjoin 比较两个表并在匹配可用时返回数据,否则返回 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() 函数将这些值添加到范围的基准日期。
于 2009-01-15T19:24:29.047 回答
50

只有4种:

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

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

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

于 2009-01-15T19:13:21.427 回答
30

SQL JOINS 区别:

很容易记住:

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

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

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

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

在此处输入图像描述

于 2018-01-12T04:26:30.817 回答
9

在 Wikipedia 上查看Join (SQL)

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

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

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

于 2009-01-15T19:15:22.577 回答
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
于 2017-06-28T18:16:58.340 回答
4

LEFT JOINRIGHT JOIN是s的类型OUTER JOIN

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

于 2009-01-15T19:14:09.583 回答
3

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

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

于 2015-02-15T20:20:53.323 回答
2

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

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

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

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

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

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

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

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

谢谢

于 2017-11-02T15:47:16.647 回答