问题:已经有了一个查询可以返回所需要的值,还需要得到其他的信息,但当加入这些信息时,发现原始结果集中的数据有丢失。例如,要返回所有的员工信息,他们工作部门的地点及所获得的奖励。在这个问题中,表EMP_BONUS包含如下内容:
select * from emp_bonus;
+-------+------------+------+
| empno | RECEIVED | TYPE |
+-------+------------+------+
| 7269 | 2005-05-14 | 1 |
| 7788 | 2005-05-14 | 3 |
| 7900 | 2005-05-14 | 2 |
+-------+------------+------+
select e.ename,d.loc from emp e,dept d
where e.deptno = d.deptno
现在将每个员工所获得的奖励的日期列加入到结果集中。
解决方案:
可以使用外联结来获得这些附加的信息,并且原始查询中的数据也不会丢失。首先,联接表emp和dept来得到所有员工姓名和他们工作的部门,然后与表emp_bonus进行外联接来返回获得奖励的日期(对获得奖励的员工)。
select e.ename ,d.loc ,eb.received
from emp e join dept d
on (e.deptno=d.deptno)
left join emp_bonus eb
on (e.empno=eb.empno)
order by 2;
还可以使用标量子查询(放在select列表中的子查询)来模仿外联结:
select e.ename,d.loc,
(select eb.received from emp_bonus eb
where eb.empno=e.empno)as received
from emp e,dept d
where e.deptno = d.deptno
order by 2;
这种标量子查询的解决方案可以在所有的平台上运行
讨论:
外联接可以返回一个表中所有行及与另一个表中匹配的行,可以看前一节有关外联结的另一个例子。因为使用外联结可以解决这个问题。次查询会返回不用外联结时应返回的所有行,并且,如果存在新加的数据也一并返回。
使用标量子查询也是解决这种问题的一个方便的技巧。因为它不需要修改已有的正确联接。使用标量子查询是不会危及到当然结果集而获得额外数据的一种简单方法。当使用标量子查询时,继续确保返回的是标量值(单个值)。如果在select列表中的子查询的返回值超过一行,将会出现错误。