新手问题:结果、SQL、连接、where子句、"<" 运算符出现问题

5
任务:
显示员工的姓氏、薪水,以及他们的经理的姓氏和薪水。我们只对那些在其经理之前被雇用且薪水低于其部门平均水平的员工感兴趣。
代码:
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)
  • 一个没有部门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

4
一位新用户的好问题,其中展示了问题、代码和一些数据。下次请尽量避免截图,这将更加完美。给我点赞。 - Aleksej
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
;

是的,那解决了问题。非常感谢您的帮助和编辑。 - JZal
5
@APC......它并不完全折叠成1=1。它等同于e.department_id不为空。在这种情况下没有什么区别,但在其他情况下可能会有区别。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接