Left,Right,Outer和Inner Joins之间有什么区别?
我想知道如何区分所有这些不同的连接...
简单的例子 :假设你有一个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的视觉表示
有三种基本的连接类型:
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()函数将这些值添加到范围的基准日期。 上一篇: What is the difference between Left, Right, Outer and Inner Joins?
下一篇: Combine two data frames with different number of rows in R