新手问题:结果问题,sql,join,where,“

问题描述 投票:5回答: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(e.salary) 
                  from employees e  
                  where e.department_id=e.department_id) 
and e.hire_date < m.hire_date

问题:

我的结果有问题。其中我得到了

  • 一名员工的薪水等于部门平均水平(Rajs)
  • 一个没有department_id的员工(Grant)
  • 一名在单人部门工作的员工(Whalen)。

然而,当我在<e.salary < (select avg(e.salary)...之间改变>算子时(假设这次我们对那些薪水高于部门平均水平的人感兴趣),结果是正确的。

我无法理解为什么它以这种方式工作?我试图通过添加此行来解决此问题

 and e.salary<>(select avg(e.salary) 
               from employees e 
               where e.department_id=e.department_id)`

但它不起作用。任何人都可以帮助我了解正在发生的事情或只是显示方向吗?

这是我的桌子:enter image description here

sql oracle subquery where
1个回答
7
投票

这是一个微妙的问题。在子查询中,您有别名的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
;
© www.soinside.com 2019 - 2024. All rights reserved.