修改emp_bonus表,使得在部门10中并不是每个员工都有奖金。
select deptno ,
sum(sal) as total_sal,
sum(bonus) as total_bonus
from (
select e.empno,
e.name,
e.sal,
e.deptno,
e.sal*case when eb.type = 1 then .1
when eb.tyoe = 2 then .2
else .3 end as bonus
from emp e, emp_bonus ed
where e.empno = eb.empno
and e.deptno = 10
)
group by deptno
total_bonus的结果是正确的,但是total_sal的值却不能体现在部门10中所有员工的工资。下面的查询课揭示total_sal不正确的原因:
select e.empno,
e.ename,
e.sal,
e.deptno,
e.sal*case when eb.type = 1 then .1
when eb.type = 2 thrn .2
else .e end as bonus
from emp e ,emp_bonus eb
where e.empno = eb.empno
and e.deptno = 10
与其说是汇总了部门10中所有员工的工资,不如说是只汇总了‘miller’ 一个人的工资,而且还被错误的汇总了两次。
解决方案:
此问题的解决方案与3.9中的解决方案类似,但是这里应当对应表emp_bonus使用外联接来确保部门10中所有员工都包含到结果中。
DB2、MySQL、PostgreSQL和 SQL Server
外联结到表emp_bonus,然后只对部门10中不同的工资进行汇总:
select deptno,
sum(distinct sal) as total_sal,
sum(bonus) as total_bonus
from (
select e.empno,
e.ename,
e.sal,
e.deptno,
e.sal*case when eb.type is null then 0
when eb.type = 1 then .1
when eb.type = 2 then .2
else .3 end as bonus
from emp e left outer join emp_bonus eb
on (e.deptno = eb.deptno)
where e.deptno = 10
)
group by deptno
也可以使用窗口函数 sum over:
select distinct deptno,total_sal,total_bonus
from (
select e.empno,
e.ename,
sum(distinct e.sal) over
(partition by e.deptno) as total_sak,
e.deptno,
sum(e.sal*case when eb.type is null then 0
when eb.type = 1 then .1
when eb.type = 2 then .2
else .3
end) over
(partition by deptno) as total_bonus
from emp e left outer join emp_bonus eb
on (e.empno = eb.empno)
where e.deptno = 10
)x