9.3.4 外连接(OUTER JOIN)
不管是内连接还是带WHERE子句的多表查询,都组合自多个表,并生成结果表。换句话说,如果任何一个源表中的行在另一个源表中没有匹配,DBMS将不把该行放在最后的结果表中。
而外连接告诉ODBC生成的结果表,不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。
SQL的外连接共有3种类型:左外连接,关键字为LEFT OUTER JOIN、右外连接,关键字为RIGHT OUTER JOIN和全外连接,关键字为FULL OUTER JOIN。外连接的用法和内连接一样,只是将INNER JOIN关键字替换为相应的外连接关键字即可。
说明 使用外连接时,关键字OUTER是可选的,如可用LEFT JOIN替代LEFT OUTER JOIN。
下面分别介绍一下这几种外连接方式。
1.左外连接
左外连接,LEFT OUTER JOIN,告诉DBMS生成的结果表中,除了包括匹配行外,还包括JOIN关键字(FROM子句中)左边表的不匹配行。左外连接实际上可以表示为:
左外连接 = 内连接 + 左边表中失配的元组
其中,缺少的右边表中的属性值用NULL表示。图9.17给出了典型的左外连接示意图。
图9.17 左外连接 |
实例11 左连接STUDENT表和COURSE表
左连接STUDENT表和COURSE表,查询所有同学的学号、姓名、课程代码、课程名称、考试时间和成绩信息。实例代码:
SELECT S.SNO, SNAME, S.CNO, CNAME, CTEST, MARK |
运行结果如图9.18所示。
可见,最终得到的结果表中,除了包括两个表匹配的行(3~20行),还包括了左边表STUDENT中的不匹配行(1、2行),缺少的右边表,即COURSE表中的属性值用NULL表示。
技巧 在SQL Server中,可以在WHERE子句中使用“*=”符号实现左外连接。
图9.18 左连接STUDENT表和COURSE表的查询结果 |
在WHERE子句,使用“*=”符号实现左外连接实现上例,代码如下。
SELECT S.SNO, SNAME, S.CNO, CNAME, CTEST, MARK |
运行结果如图9.19所示。
图9.19 使用“*=”符号实现的左外连接 |
说明 在Oracle数据库系统中,只需将“*=”替换成“+=”可以得到相同的结果。
2.右外连接
右外连接(RIGHT OUTER JOIN)告诉DBMS生成的结果表中,除了包括匹配行外,还包括JOIN关键字(FROM子句中)右边表的不匹配行。右外连接实际上可以表示为:
右外连接 = 内连接 + 右边表中失配的元组 |
其中,缺少的左边表中的属性值用NULL表示。图9.20给出了典型的右外连接示意图。
图9.20 右外连接 |
实例12 右外连接STUDENT表和COURSE表
右外连接STUDENT表和COURSE表,查询所有同学的学号、姓名、课程代码、课程名称、考试时间和成绩信息。实例代码:
SELECT S.SNO, SNAME, S.CNO, CNAME, CTEST, MARK |
运行结果如图9.21所示。
图9.21 右外连接STUDENT表和COURSE表的查询结果 |
可见,最终得到的结果表中,除了包括两个表匹配的行(3~20行),还包括了右边表COURSE表中的不匹配行(1、2行),缺少的左边表,即STUDENT表中的属性值用NULL表示。
技巧 在SQL Server数据库系统中,可以在WHERE子句中使用“=*”符号实现右外连接。
实例13 在WHERE子句中使用“=*”符号实现右外连接
在WHERE子句,使用“=*”符号实现实例12,代码如下。
SELECT S.SNO, SNAME, S.CNO, CNAME, CTEST, MARK |
运行结果如图9.22所示。
图9.22 使用“=*”符号实现的右外连接 |
3.全外连接
全外连接,FULL OUTER JOIN,告诉DBMS生成的结果表中,除了包括匹配行外,还包括JOIN关键字(FROM子句中)左边表和右边表的不匹配行。全外连接实际上可以表示为:
全外连接 = 内连接 + 左边表中失配的元组 + 右边表中失配的元组。 |
其中,缺少的左边表或者右边表中的属性值用NULL表示。图9.23给出了典型的全外连接示意图。
图9.23 全外连接 |
实例14 全外连接STUDENT表和COURSE表
全外连接STUDENT表和COURSE表,查询所有同学的学号、姓名、课程代码、课程名称、考试时间和成绩信息。实例代码:
SELECT S.SNO, SNAME, S.CNO, CNAME, CTEST, MARK |
运行结果如图9.24所示。
图9.24 全外连接STUDENT表和COURSE表的查询结果 |
可见,最终得到的结果表中,除了包括两个表匹配的行(5~22行),还包括了右边表COURSE表中的不匹配行(1、2行),缺少的左边表,即STUDENT表中的属性值用NULL表示。以及左边表,STUDENT表中的不匹配行(3、4行),缺少的右边表,即COURSE表中的属性值用NULL表示。