这一篇文章要总结的是用得最多的联接查询即外联接查询,外联接查询相对于交叉联接和内联接来说要更复杂一些,我准备从以下几个方面对外联接进行总结。
1,什么是外联接查询
2,一个外联接查询的例子
3,关于外联接查询的总结
什么是外联接查询
外联接除了有内联接的两个逻辑处理步骤(即笛卡尔积和ON过滤)之外,还多加一个外联接特有的第三步:添加外部行。
在外联接中,需要将一个表标记为保留表,在两个表之间用LEFT OUTER JOIN连接(OUTER是可选的),LEFT关键字左边表的行是保留的。外联接的第三个逻辑查询处理步骤就是要识别保留表中按照ON条件在另一个表中找不到与之匹配的那些行,然后将这些行添加到联接的前两个步骤生成的结果表中。对于来自联接的非保留表的那些列,追加的外部行中的这些列则用NULL作为占位符。
一个外联接查询的例子
下面的例子查询根据客户的客户ID和订单的客户ID对Customers表和Orders表进行联接,并返回客户和他们的订单信息。该联接是使用的左外联接,所以查询结果会返回那些没有发出任何订单的客户。
SQL查询代码:
-- LEFT JOIN外联接查询 SELECT customers.custid,customers.companyname,orders.orderid FROM Sales.Customers AS customers LEFT JOIN Sales.Orders AS orders ON customers.custid = orders.custid;
查询结果:
查询共返回832行,但是,Customers表中有两个客户没有任何订单,他们的ID分别是22和57。从逻辑上来说,与这两个客户相关的数据行在联接的第二步(基于ON条件过滤)就被过滤掉了,而在第三步又把这些行作为外部行添加进来了。如果使用的内联接,结果将不会返回这两行。添加这两行后,就可以在结果中保留左边表的所有行。
关于外联接查询的总结
对于外联接查询的总结,需要注意以下几点:
- 从外联接保留表的角度看,可以认为外联接结果的数据行包括两种:内部行和外部行。内部行是按照ON子句的条件能在联接的另一边找到匹配的那些行;而外部行则是指找不到匹配的那些行。内联接只返回内部行,而外联接同时返回内部行和外部行。
- 使用外联接的时候,经常会为到底是在查询的ON子句中,还是在WHERE子句中指定联接条件而困惑。现在的结论是,当需要表达一个非最终的条件时(即这个条件只决定哪些行可以匹配非保留表),就在ON子句中指定联接条件;当在生成外部行后,要应用过滤器,并且希望过滤条件是最终的,就应该在WHERE子句中指定条件。
- 当查找NULL值时,应该使用IS NULL运算符,而不是直接使用等号,因为等号会把任何值与NULL进行比较时,总是会返因UNKNOWN---即使对两个NULL值进行比较也是这样。
- 选择联接的非保留表中的哪个列作为过滤器也很重要。应该选择只在外部行才取值为NULL,而在其他行取值不为NULL的某个列。为此,有三种情形可以考虑安全地使用,主键列,联接列,以及定义为NOT NULL的列。具体可以参考下面的查询代码。
SELECT customers.custid,customers.companyname,orders.orderid FROM Sales.Customers AS customers LEFT JOIN Sales.Orders AS orders ON customers.custid = orders.custid WHERE orders.orderid IS NULL -- 使用主键列 -- WHERE orders.custid IS NULL --使用联接列 -- WHERE orders.orderdate IS NULL -- 使用NOT NULL列
查询结果: