任务:
显示员工的姓氏,员工薪水及其经理的姓氏和薪水。我们只对那些在经理之前被雇用并且薪水低于其部门平均水平的员工感兴趣。
码:
select e.last_name, e.salary, e.hire_date, e.department_id,
m.last_name, m.salary, m.hire_date
from employees e
join employees m on (e.manager_id=m.employee_id)
where e.salary <(select avg(e.salary)
from employees e
where e.department_id=e.department_id)
and e.hire_date < m.hire_date
问题:
我的结果有问题。其中我得到了
然而,当我在<
和e.salary < (select avg(e.salary)...
之间改变>
算子时(假设这次我们对那些薪水高于部门平均水平的人感兴趣),结果是正确的。
我无法理解为什么它以这种方式工作?我试图通过添加此行来解决此问题
and e.salary<>(select avg(e.salary)
from employees e
where e.department_id=e.department_id)`
但它不起作用。任何人都可以帮助我了解正在发生的事情或只是显示方向吗?
这是一个微妙的问题。在子查询中,您有别名的employees e
,它与您在主查询中使用的别名相同。这意味着子查询e.department_id=e.department_id
中的过滤器实际上并不像您认为的那样:由于命名空间作用域,它实际上会折叠到1=1
。所以你没有得到你期望的结果,因为子查询没有相关性。
解决方案很简单:在子查询中使用不同的别名,如下所示:
select e.last_name, e.salary, e.hire_date, e.department_id,
m.last_name, m.salary, m.hire_date
from employees e
join employees m on (e.manager_id=m.employee_id)
where e.salary <(select avg(e2.salary)
from employees e2
where e.department_id=e2.department_id)
and e.hire_date < m.hire_date
;