Вопрос новичка: проблема с результатами, sql, join, где, оператор "<" - PullRequest
0 голосов
/ 03 сентября 2018

ЗАДАНИЕ:

Показать фамилии работников, зарплату сотрудников и их руководителей фамилии и зарплата. Нас интересуют только те сотрудники, которые были наняты раньше своих менеджеров и имеют зарплату ниже среднего их отделов.

КОД:

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

ПРОБЛЕМА:

У меня проблема с результатами. Среди них я получил

  • один сотрудник с зарплата равна средней по отделу (раджи)
  • один работник без отдела_ид (Грант)
  • один сотрудник, который работает в отделе с одним человеком (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

1 Ответ

0 голосов
/ 03 сентября 2018

Это тонкая проблема. В вашем подзапросе у вас есть псевдоним 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
;
...