此外LEFT JOIN,RIGHT JOIN和FULL JOIN适合吗?
假设您加入没有重复的列,这是一个非常常见的情况:
例子
假设您有两个表,每个表有一列,数据如下:
A B - - 1 3 2 4 3 5 4 6
请注意,(1,2) 是 A 独有的,(3,4) 是通用的,而 (5,6) 是 B 独有的。
内部联接
使用任一等效查询的内部联接给出两个表的交集,即它们共有的两行。
select * from a INNER JOIN b on a.a = b.b; select a.*, b.* from a,b where a.a = b.b; a | b --+-- 3 | 3 4 | 4
左外连接
左外连接将给出 A 中的所有行,以及 B 中的所有公共行。
select * from a LEFT OUTER JOIN b on a.a = b.b; select a.*, b.* from a,b where a.a = b.b(+); a | b --+----- 1 | null 2 | null 3 | 3 4 | 4
右外连接
右外连接将给出 B 中的所有行,以及 A 中的所有公共行。
select * from a RIGHT OUTER JOIN b on a.a = b.b; select a.*, b.* from a,b where a.a(+) = b.b; a | b -----+---- 3 | 3 4 | 4 null | 5 null | 6
全外连接
一个完整的外连接会给你 A 和 B 的联合,即 A 中的所有行和 B 中的所有行。如果 A 中的某些内容在 B 中没有相应的数据,则 B 部分为空,反之亦然反之。
select * from a FULL OUTER JOIN b on a.a = b.b; a | b -----+----- 1 | null 2 | null 3 | 3 4 | 4 null | 6 null | 5
维恩图并不适合我。
例如,它们没有显示交叉连接和内部连接之间的任何区别,或者更一般地显示不同类型的连接谓词之间的任何区别,或者提供一个框架来推理它们将如何操作。
理解逻辑处理是无可替代的,无论如何掌握起来都相对简单。
on
true
(注意:在实践中,查询优化器可能会找到比上面纯逻辑描述更有效的查询执行方式,但最终结果必须相同)
我将从一个完整的外连接的动画版本开始。进一步的解释如下。
源表
首先从CROSS JOIN(又名笛卡尔积)开始。这没有ON子句,只是返回两个表中行的每个组合。
CROSS JOIN
ON
从 A CROSS JOIN B 中选择 A.Colour、B.Colour
内连接和外连接有一个“ON”子句谓词。
SELECT A.Colour, B.Colour from A INNER JOIN B ON A.Colour = B.Colour
以上是经典的equi join。
内连接条件不一定是相等条件,也不需要引用来自两个(或什至其中一个)表的列。A.Colour NOT IN ('Green','Blue')对交叉连接返回的每一行进行评估。
A.Colour NOT IN ('Green','Blue')
SELECT A.Colour, B.Colour from A INNER JOIN B ON 1 =1
对于交叉联接结果中的所有行,联接条件的计算结果为真,因此这与交叉联接相同。16行的图我就不重复了。
外连接的逻辑评估方式与内连接相同,不同之处在于如果左表中的一行(对于左连接)根本不与右手表中的任何行连接,它会保留在结果中,其NULL值为右手边的列。
NULL
这只是将先前的结果限制为仅返回 where 的行B.Colour IS NULL。在这种特殊情况下,这些将是保留的行,因为它们在右侧表中没有匹配项,并且查询返回表中不匹配的单个红色行B。这被称为反半连接。
B.Colour IS NULL
B
为IS NULL测试选择一列不可为空或连接条件确保NULL将排除任何值以便此模式正常工作并避免仅带回恰好具有该NULL值的行很重要除了未匹配的行之外的列。
IS NULL
右外连接的作用类似于左外连接,除了它们保留右表中不匹配的行并且 null 扩展左手列。
全外连接结合了左右连接的行为,并保留了左右表中不匹配的行。
交叉联接中没有任何行与1=0谓词匹配。两侧的所有行都使用普通外连接规则保留,另一侧表的列中为 NULL。
1=0
对前面的查询稍作修改,就可以模拟UNION ALL两个表中的一个。
UNION ALL
请注意,WHERE子句(如果存在)在连接之后在逻辑上运行。一个常见的错误是执行左外连接,然后在右表上包含一个 WHERE 子句,该子句最终排除了不匹配的行。以上最终执行外连接......
WHERE
…然后“Where”子句运行。NULL= 'Green'不评估为真,因此外部连接保留的行最终被丢弃(连同蓝色)有效地将连接转换回内部连接。
NULL= 'Green'
如果意图是仅包括来自 B 的行,其中颜色为绿色,而不管正确的语法是来自 A 的所有行