首页 > 代码库 > 3.6 向查询中增加联接而不影响其他联接

3.6 向查询中增加联接而不影响其他联接


问题;已经有了一个查询可以返回所需要的值,还需要得到其他的信息,但当加入这些信息时,发现原始结果集中的数据有丢失。例如,要返回所有的员工信息,他们工作部门的地点及所获得的奖励。

select e.ename,d.loc from emp e,dept d
    where e.deptno = d.deptno

现在将每个员工所获得的奖励的日期列加入到结果集中,但是连接到emp_bonus表后,所返回的记录数要比所希望的要少,因为并不是每个员工都有奖励:

select e.ename,d.loc,eb.received from emp e,dept d,emp_bonus eb
    where e.deptno = d.deptno and e.empto=eb.empno

解决方案:
可以使用外联结来获得这些附加的信息,并且原始查询中的数据也不会丢失。首先,联接表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.enmae=eb.ename)
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列表中的子查询的返回值超过一行,将会出现错误。

3.6 向查询中增加联接而不影响其他联接