提问



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

最佳参考


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


每个学生都可以分配到一个储物柜,因此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个储物柜)。可能有用(使用过滤)作为一个起点,以匹配新学生与空储物柜。

其它参考1


这是所有连接的图形视图,提供清晰的视觉解释。





在这里 C.L详细解释 Visual-Representation-of-SQL-Joins 。莫法特 [32] [33]

其它参考2


有三种基本类型的连接:



  • INNER join比较两个表,只返回匹配存在的结果。第一个表中的记录在第二个表中匹配多个结果时会重复。 INNER连接倾向于使结果集更小,但因为记录可以重复,所以不能保证。

  • CROSS join比较两个表并返回两个表中每个可能的行组合。您可以从这种可能甚至没有意义的联接中获得大量结果,因此请谨慎使用。

  • OUTER join比较两个表并在匹配可用时返回数据,否则返回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:您想要从Invoice表中返回所有记录及其对应的InvoiceLines。这假设每个有效的发票都至少有一行。

  • OUTER:您希望返回特定发票的所有InvoiceLines记录及其对应的InventoryItem记录。这是一个也销售服务的企业,因此并非所有InvoiceLines都有IventoryItem。

  • CROSS:您有一个包含10行的数字表,每行包含值0到9。您希望创建要加入的日期范围表,以便最终在该范围内的每一天记录一条记录。通过CROSS将该表与其自身重复连接,您可以根据需要创建任意数量的连续整数(假设您从10到1次幂开始,每个连接将1加到指数中)。然后使用DATEADD()函数将这些值添加到范围的基准日期。


其它参考3


只有4种:



  1. 内部联接:最常见的类型。为连接条件匹配的每对输入行生成输出行。

  2. 左外连接:与内连接相同,只是如果有任何行可以找到右侧表中没有匹配的行,则输出包含值的行从左边的表格中,右边的表格中的每个值都有NULL。这意味着左侧表格中的每一行在输出中至少出现一次。

  3. 右外连接:与左外连接相同,但表格的角色相反。

  4. 全外连接:左外连接和右外连接的组合。两个表中的每一行都至少会在输出中出现一次。



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


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

其它参考4


在Wikipedia上查看Join(SQL)[34]



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

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

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

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


其它参考5


SQL JOINS的区别:


很容易记住:


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


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


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


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


[35]

其它参考6


LEFT JOINRIGHT JOINOUTER JOIN的类型。


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

其它参考7


内部联接:仅显示行,何时从两个表中获取数据。


外部联接:(左/右):使用配对行显示左/右表中的所有结果( s ),如果它存在。

其它参考8


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


表格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

其它参考9


首先你必须了解加入做什么?我们连接多个表并从连接表中获取特定结果。最简单的方法是交叉连接


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


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


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


内心:这就像交集。它将仅返回来自两个表的匹配记录。


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


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


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


谢谢