外连接和WHERE子句

PostgreSQL 分别支持传统的连接语法(用WHERE 子句去指定连接的列)和ANSI标准的连接语法(在FROM子句中使用JOIN关键字)。在PostgreSQL中,这两种语法都可以用于内连接,但只有ANSI标准的连接语法支持外连接。

我们需要注意这样一种情况:

虽然列约束和连接没有关系,但列约束出现在WHERE子句和部分JOIN子句中时效果不总是相同的。

JOIN子句中的约束是在连接的过程中被处理的,但WHERE子句中的约束却是在连接之后才被处理的。

这种差别只有在外连接(和交叉连接)中才会显著表现出来,因为未被连接的行中的列会被外连接使用。

举个例子:

外连接和WHERE子句

图1

我们可以从图1的结果中看出,第一次SELECT语句执行了没有列约束的外连接。

外连接和WHERE子句

图2

第二次SELECT语句返回的信息和第一次相同(见图2),这是因为列约束和test2这张表中所有的行都匹配。

外连接和WHERE子句

图3

最后一次SELECT语句基于外连接的结果执行(见图3),因为判断null<=2会返回null,第三次输出的行会被掩盖。

然后我们来看列约束是如何造成正常情况下全部连接的查询会返回未连接的列值。

外连接和WHERE子句

图4

向test2表中插入值3。

外连接和WHERE子句

图5

在图5所示的第二次SELECT语句中,test2.x中值为3的会被排除在连接之外,导致外连接结果里这一列中对应的值为NULL。

综上所述:

我们在使用外连接时,必须注意外连接查询的内侧表中约束子句使用的位置,而且还要明确约束发生的时间,在连接的时候还是连接之后。

参考文献:

1、PostgreSQL 9.6.7 Documentation

2、PostgreSQL Introduction and Concepts