我想知道如何区分所有这些不同的连接......
答案 0 :(得分:772)
简单示例:假设您有一个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个储物柜)。可能是有用的(使用过滤)作为一个起点,以匹配新学生与空储物柜。
答案 1 :(得分:138)
联接有三种基本类型:
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
:您想要从“发票”表中返回所有记录及其对应的“InvoiceLines”。这假定每个有效的发票都至少有一行。OUTER
:您希望返回特定发票的所有“InvoiceLines”记录及其对应的“InventoryItem”记录。这是一个也销售服务的企业,因此并非所有InvoiceLines都有IventoryItem。CROSS
:您有一个包含10行的数字表,每行包含值“0”到“9”。您希望创建要加入的日期范围表,以便最终在该范围内的每一天都有一条记录。通过CROSS将该表与其自身重复连接,您可以根据需要创建任意数量的连续整数(假设从10到1次幂开始,每个连接将1加到指数中)。然后使用DATEADD()函数将这些值添加到范围的基准日期。答案 2 :(得分:47)
只有4种:
NULL
。这意味着左侧表格中的每一行在输出中至少出现一次。 “交叉连接”或“笛卡尔连接”只是一个内连接,没有指定连接条件,导致输出所有行对。
感谢RusselH指出FULL联接,我省略了。
答案 3 :(得分:16)
SQL JOINS差异:
很容易记住:
INNER JOIN
仅显示两个表共有的记录。
OUTER JOIN
两个表中的所有内容都会合并在一起,无论它们是否匹配。
LEFT JOIN
与LEFT OUTER JOIN
相同 - (从第一个(最左侧)表中选择具有匹配的右表记录的记录。)
RIGHT JOIN
与RIGHT OUTER JOIN
相同 - (从第二个(最右侧)表中选择具有匹配左表记录的记录。)
答案 4 :(得分:9)
左/右(外)连接 - 给定两个表返回连接的左表或右表中存在的所有行,当join子句匹配时,将返回另一侧的行这些列
Full Outer - 给定两个表返回所有行,并且当左列或右列不存在时将返回空值
交叉连接 - 笛卡尔连接,如果不小心使用会很危险
答案 5 :(得分:4)
LEFT JOIN
和RIGHT JOIN
是OUTER JOIN
的类型。
INNER JOIN
是默认值 - 两个表中的行必须与连接条件匹配。
答案 6 :(得分:3)
内部联接:仅显示行,何时从两个表中获取数据。
外部联接:(左/右):使用配对行显示左/右表中的所有结果( s ),如果它存在。
答案 7 :(得分:2)
让它更加明显可能有所帮助。一个例子:
表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
答案 8 :(得分:1)
首先你必须了解加入做什么?我们连接多个表并从连接表中获取特定结果。最简单的方法是交叉连接。
让我们说tableA有两列A和B.而tableB有三列C和D. 如果我们应用交叉连接,它将产生许多无意义的行。然后我们必须使用主键进行匹配才能获得实际数据。
左:它将返回左表中的所有记录和右表中的匹配记录。
右:它将返回与左连接相反的位置。它将返回右表中的所有记录和左表中匹配的记录。
内心:这就像交集。它只返回两个表中匹配的记录。
外面:这就像工会一样。它将从两个表中返回所有可用记录。
有些时候我们不需要所有数据,而且我们也只需要通用数据或记录。我们可以使用这些连接方法轻松获取它。记住左右连接也是外连接。
您可以使用交叉连接获取所有记录。但是,涉及数百万条记录时,它可能会很昂贵。因此,使用左,右,内或外连接使其变得简单。
感谢