3.9 外连接

  在介绍外连接之前,先要了解什么是内连接以及内连接和等值连接的关系。在标准SQL中,将两个表连接,仅返回匹配条件的行的连接称为内连接。等值连接是内连接的一种,因为等值连接仅返回满足等值条件的行。相对于等值连接而言,另外一种内连接就是非等值连接,也就是说连接条件不是“=”,而返回的行仅为满足这个非“=”连接条件的行。

3.9.1 非等值内连接

  为了演示非等值内连接的效果,为HR用户新建了一个表,其表结构和表内容分别如图3.18和图3.19所示。具体如何创建表,在后面的内容中将会详细介绍。

3.9 外连接 - 图1


图3.18 员工分类表结构

3.9 外连接 - 图2


图3.19 员工分类表内容

  从图3.18和图3.19可以看出,公司将员工分为A、B、C、D四类,分类依据为雇员的雇佣日期。现在需要查询出雇员的名字、薪水和所属分类,其SQL语句如下:

  1. SELECT e.first_name, e.salary, eg.e_grade
  2. FROM employees e,egrade eg
  3. WHERE e.hire_date BETWEEN eg.hire_start AND eg.hire_end

  这段SQL语句的比较条件是判断日期是否在一个范围内,不是“=”,所以不是等值连接,其返回的结果仅为满足比较条件的行,所以该连接是非等值内连接。执行该SQL语句,部分显示结果如图3.20所示。

3.9 外连接 - 图3


图3.20 非等值内连接

3.9.2 左外连接、右外连接、全外连接、笛卡儿积

  • 左外连接

  左外连接又称左连接,指在两个表之间的连接,返回内连接的结果,同时还返回左表中未匹配的行,右表中相应字段置空。接下来对employees表和departments表进行左连接, employees表作为左表,departments表作为右表,使用左连接的SQL语句如下:

  1. SELECT e.first_name, e.department_id, d.department_name
  2. FROM employees e
  3. LEFT OUTER JOIN departments d
  4. ON (e.department_id = d.department_id)

  执行该SQL语句,部分显示结果如图3.21所示。

3.9 外连接 - 图4


图3.21 左外连接

  从图3.21中可以看出,左连接在内连接的基础上,将左表(employees)中未匹配的行也查询出来,右表中相应字段为空。

  上面是一种左连接的写法,看起来略微有些复杂,下面的SQL语句同样完成了上面左连接的功能,不过在书写和阅读上都容易许多。

  1. SELECT e.first_name, e.department_id, d.department_name
  2. FROM employees e,departments d
  3. WHERE e.department_id = d.department_id(+)

  这段SQL语句和等值连接类似,只是在等号的某一边加上了一个“(+)”,这个“(+)”应该被放置在不需要增加未匹配的行的表的一侧。采用“(+)”进行外连接,不存在左表和右表之分,并且不可以在比较条件的两边都放“(+)”。

  • 右外连接

  右外连接又称右连接,和左连接正好相反。接下来仍然对employees表和departments表进行右连接,employees表作为左表,departments表作为右表,使用右连接的SQL语句如下:

  1. SELECT e.first_name, department_id, d.department_name
  2. FROM employees e
  3. RIGHT OUTER JOIN departments d
  4. USING(department_id)

  执行该SQL语句,部分显示结果如图3.22所示。

3.9 外连接 - 图5


图3.22 右外连接

  用“(+)”代替右外连接,SQL语句的具体写法如下:

  1. SELECT e.first_name, e.department_id, d.department_name
  2. FROM employees e,departments d
  3. WHERE d.department_id = e.department_id(+)
  • 全外连接

  所谓全外连接,也称全连接,是指两个表在返回内连接结果的基础上,还返回左表及右表中未匹配的行,右表及左表中相应字段置空,其SQL语句如下:

  1. SELECT e.first_name, department_id, d.department_name
  2. FROM employees e
  3. FULL OUTER JOIN departments d
  4. USING(department_id)

  执行该SQL语句,部分显示结果如图3.23所示。

3.9 外连接 - 图6


图3.23 全连接

  • 笛卡儿积

  截止到现在,所介绍的多表连接查询都有连接条件,通过连接条件对连接进行限制。如果连接条件无效或者遗漏,其结果是一个笛卡儿积,其中所有行的组合都被显示出来,即第一个表中的所有行连接到第二个表中的所有行。

  笛卡儿积会产生大量的行,例如第一个表中假设有100条记录,第二个表中有200条记录,使用笛卡儿积,结果就是两者相乘的20000条记录。这样的笛卡儿积一般来说没有什么用,所以除非有特殊的需求,应该保证连接条件正确有效,不要出现笛卡儿积的情况。