新手问题:结果问题,sql,join,where,"<"运算符

JZa*_*Zal 5 sql oracle subquery where

任务:

显示员工的姓氏,员工薪水及其经理的姓氏和薪水.我们只对那些在经理之前被雇用并且薪水低于其部门平均水平的员工感兴趣.

码:

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
Run Code Online (Sandbox Code Playgroud)

问题:

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

  • 一名员工的薪水等于部门平均水平(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)`
Run Code Online (Sandbox Code Playgroud)

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

这是我的表: 在此输入图像描述

APC*_*APC 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
;
Run Code Online (Sandbox Code Playgroud)

  • @APC...它并没有完全崩溃到"1 = 1".它相当于`e.department_id不为null`.在这种情况下不会有所不同,但在其他情况下可能会有所不同. (5认同)