左,右,外和内连接有什么区别?
我想知道如何区分所有这些不同的联接…
简单的例子 :假设你有一个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个储物柜)。 可以用(过滤)作为起点,将新学生与空的储物柜相匹配。
这里是所有连接的图形视图,给出清晰的视觉解释。
在这里,由CL Moffatt详细解释了SQL-Joining的Visual-Representation-of-SQL-Joins
有三种基本的连接类型:
-
INNER
连接比较两个表,只返回匹配存在的结果。 当第一个表格中的记录与第二个中的多个结果相匹配时,将被复制。 INNER联接倾向于使结果集更小,但是因为记录可以重复,所以不能保证。 -
CROSS
连接比较两个表,并返回两个表中每一行的可能组合。 你可以从这种连接中得到很多结果,甚至可能没有意义,所以谨慎使用。 -
OUTER
连接比较两个表,并在匹配可用时返回数据,否则返回NULL值。 与INNER连接一样,当它匹配另一个表中的多个记录时,这将在一个表中重复行。 OUTER连接往往会使结果集更大,因为它们本身不会从集合中删除任何记录。 您还必须限定OUTER连接以确定何时以及在哪里添加NULL值:-
LEFT
表示无论如何保留第一个表中的所有记录,并在第二个表不匹配时插入NULL值。 -
RIGHT
意味着相反:无论如何保留第二个表中的所有记录,并在第一个表不匹配时插入NULL值。 -
FULL
表示保留两个表中的所有记录,如果不匹配,则在任一表中插入NULL值。
-
通常你会发现语法中省略了OUTER
关键字。 相反,它只是“左连接”,“右连接”或“全连接”。 这样做是因为INNER和CROSS联接对于左,右或全部没有意义,所以这些就足以明确地指示一个OUTER联接。
以下是您可能想要使用每种类型的示例:
-
INNER
:您要从“发票”表中返回所有记录,以及相应的“发票行”。 这假定每个有效的发票至少有一行。 -
OUTER
:您希望返回特定发票的所有“InvoiceLines”记录,以及相应的“InventoryItem”记录。 这是一个也销售服务的业务,所以并不是所有的InvoiceLines都有一个IventoryItem。 -
CROSS
:你有一个10行的数字表,每个数字的值都是'0'到'9'。 您想要创建一个日期范围表来加入,以便在范围内的每一天结束一个记录。 通过将此表与自身重复连接,您可以根据需要创建尽可能多的连续整数(假设您以10到1的次方开始,每个连接将1加到指数上)。 然后使用DATEADD()函数将这些值添加到范围的基准日期。
只有4种:
- 内部连接 :最常见的类型。 为连接条件匹配的每对输入行生成一个输出行。
- 左外连接 :与内连接相同,除了如果有任何行可以找到右侧表中没有匹配的行,则会输出包含左侧表中的值的行,其中
NULL
为每个值在右边的表中。 这意味着左侧表中的每一行在输出中至少会出现一次。 - 右外连接 :与左外连接相同,但表格的角色颠倒。
- 完全外连接 :左外连接和右外连接的组合。 两个表中的每一行至少会出现在输出中一次。
“交叉连接”或“笛卡尔连接”只是一个没有指定连接条件的内部连接,导致输出所有的行对。
感谢RusselH指出FULL的联结,我省略了。
检出加入(SQL)维基百科
- 内连接 – 给定两个表,内连接返回两个表中存在的所有行
-
left / right(outer)join – 给定两个表返回存在于你的连接的左边或右边表中的所有行,当连接子句匹配时返回另一边的行,否则返回null那些专栏
-
完全外部 – 给定两个表返回所有行,并且当左边或右边列不在那里时将返回空值
-
交叉连接 – 笛卡尔连接,如果不小心使用,可能会很危险
LEFT JOIN
和RIGHT JOIN
是OUTER JOIN
的类型。
INNER JOIN
是缺省值 – 两个表中的行必须匹配连接条件。
内部连接 :当两个表都有数据时,只显示行。
外连接 :( 左/右) :如果存在或不存在 ,则从左/右表格中显示所有结果行。
使其更明显可能会有所帮助。 一个例子:
表格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
起初,你必须了解什么加入呢? 我们连接多个表,并从连接的表中获得特定的结果。 最简单的方法是交叉连接 。
假设tableA有两列A和B. tableB有三列C和D.如果我们应用交叉连接会产生很多没有意义的行。 然后我们必须使用主键匹配来获得实际的数据。
左:它将从左表中返回所有记录,并从右表返回匹配的记录。
右:它将返回与左连接相反。 它将从右表中返回所有记录,并从左表中返回匹配的记录。
内在:这就像交集。 它将只返回来自两个表的匹配记录。
外:这就像联盟。 它会从这两个表中返回所有可用的记录。
有时我们不需要所有的数据,而且我们也只需要通用数据或记录。 我们可以很容易地使用这些连接方法。 记得左右连接也是外连接。
您可以使用交叉连接来获取所有记录。 但是涉及到数百万条记录可能会很昂贵。 所以通过使用左,右,内部或外部连接来简化。
谢谢