我想知道如何区分所有这些不同的联接...
我想知道如何区分所有这些不同的联接...
Answers:
简单示例:假设您有一个Students
表和一个Lockers
表。在SQL中,在联接中指定的第一个表Students
是LEFT表,第二个表Lockers
是RIGHT表。
每个学生都可以分配到一个储物柜,因此表中有一LockerNumber
列Student
。一个单独的储物柜中可能有多个学生,但是特别是在学年开始时,您可能会有一些没有储物柜的新来学生和一些没有分配学生的储物柜。
就本例而言,假设您有100名学生,其中70名有储物柜。您总共有50个储物柜,其中40个至少有1个学生,而10个没有学生。
INNER JOIN相当于“ 向我展示所有带储物柜的学生 ”。
任何没有储物柜的学生,或者没有学生的储物柜都将丢失。
返回70行
左外联接将是“ 向我显示所有学生,如果有的话,还带他们相应的储物柜 ”。
这可能是普通学生名单,或者可以用来识别没有储物柜的学生。
返回100行
正确的外部联接将是“ 显示所有储物柜,如果有的话,请分配给他们的学生 ”。
这可用于识别没有分配学生的储物柜,或拥有太多学生的储物柜。
返回80行(40个储物柜中的70个学生列表,外加10个没有学生的储物柜)
FULL OUTER JOIN会很愚蠢,可能用处不大。
例如“ 向我显示所有学生和所有储物柜,并在可以的地方进行匹配 ”
返回110行(所有100名学生,包括那些没有储物柜的学生。还有10个没有学生的储物柜)
在这种情况下,CROSS JOIN也相当愚蠢。
它不使用lockernumber
students表中的链接字段,因此,基本上,无论是否存在,您最终都会得到一个巨大的巨型列表,其中列出了每个可能的学生与储物柜配对。
返回5000行(100个学生x 50个储物柜)。可能有用(带有过滤功能)作为起点,将新学生与空的储物柜相匹配。
SELECT * FROM students RIGHT OUTER JOIN lockers...
将导致与结果不同的结果SELECT * FROM lockers RIGHT OUTER JOIN students...
。很好的答案,但希望看到它带有完整的SQL
查询进行更新
联接有三种基本类型:
INNER
联接比较两个表,仅返回存在匹配项的结果。当第一个表中的记录与第二个中的多个结果匹配时,它们将被复制。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'的值。您想要创建一个要联接的日期范围表,以便最终获得该范围内每天的一条记录。通过将此表与自身交叉连接,可以创建所需的任意多个连续整数(假设您以10到1的幂开始,则每个联接将1加到指数上)。然后,使用DATEADD()函数将这些值添加到范围的基准日期。只有4种:
NULL
,每个行对应右边表格中的值。这意味着左侧表中的每一行将在输出中至少出现一次。 “交叉联接”或“笛卡尔联接”只是内部联接,没有为其指定联接条件,从而导致输出所有成对的行。
感谢RusselH指出FULL JOIN,我省略了。
SQL JOINS的区别:
记住很简单:
INNER JOIN
仅显示两个表共有的记录。
OUTER JOIN
两个表的所有内容都被合并在一起,无论它们是否匹配。
LEFT JOIN
与LEFT OUTER JOIN
- 相同(从第一个(最左侧)表中选择具有匹配的右表记录的记录。)
RIGHT JOIN
与RIGHT OUTER JOIN
- 相同(从第二个(最右)表中选择具有匹配的左表记录的记录。)
左/右(外部)联接-给定两个表返回联接的左表或右表中存在的所有行,并且当join子句匹配时返回另一侧的行,或者返回null那些专栏
完整外部-给定两个表返回所有行,并且当左或右列都不存在时将返回null
交叉连接-笛卡尔连接,如果使用不当会很危险
使它更加可见可能会有所帮助。一个例子:
表格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
首先,您必须了解join的作用?我们连接多个表并从联接的表中获取特定结果。最简单的方法是交叉联接。
假设tableA有两列A和B。而tableB有三列C和D。如果应用交叉联接,它将产生很多毫无意义的行。然后我们必须使用主键进行匹配以获取实际数据。
左:它将返回左表中的所有记录以及右表中的匹配记录。
右:它将返回与左联接相反的方向。它将返回右表中的所有记录以及左表中的匹配记录。
内部:这就像十字路口。它将只返回两个表中匹配的记录。
外层:这就像工会。它将返回两个表中的所有可用记录。
有时我们不需要所有数据,也应该只需要公用数据或记录。我们可以使用这些join方法轻松获得它。记住左右连接也是外部连接。
您可以使用交叉连接获取所有记录。但是当涉及到数百万条记录时,它可能会很昂贵。因此,使用左,右,内部或外部联接使其简单。
谢谢