Oracle покажет всем сотрудникам с зарплатой выше среднего их отдела - PullRequest
3 голосов
/ 22 октября 2010

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

У меня есть запрос, который почти работает, но он продолжает выдавать ошибки «ORA-00904:« AVG_SAL »: неверный идентификатор». Я делаю это правильно. Почему я получаю эту ошибку неверного идентификатора?

SELECT employee_id, salary, department_id,
  (SELECT ROUND(AVG(salary),2)
  FROM employees e_inner
  WHERE e_inner.department_id = e.department_id) AS avg_sal
FROM employees e
WHERE salary > avg_sal
ORDER BY avg_sal DESC

Ответы [ 4 ]

13 голосов
/ 22 октября 2010

Более эффективно использовать аналитику:

select employee_id, salary, department_id, avg_sal
from
(
  SELECT employee_id, salary, department_id, 
    round(avg(salary) over (partition by department_id), 2) avg_sal
  from emp
)
where salary > avg_sal
order by avg_sal desc
3 голосов
/ 22 октября 2010

Вы можете переписать его как объединение:

SELECT  e1.employee_id
,       e1.salary
,       e1.department_id
,       ROUND(AVG(e2.salary),2) as Avg_Sal
FROM    employees e
JOIN    employees e2
ON      e2.department_id = e.department_id
GROUP BY
        e1.employee_id
,       e1.salary
,       e1.department_id
HAVING  e1.salary > ROUND(AVG(e2.salary),2)

Или подзапрос:

SELECT  *  
FROM    (
        SELECT  employee_id
        ,       salary
        ,       department_id
        ,       (
                SELECT  ROUND(AVG(salary),2)
                FROM    employees e_inner
                WHERE   e_inner.department_id = e.department_id
                ) AS avg_sal
        FROM    employees e
        ) as SubqueryAlias
WHERE   salary > avg_sal
3 голосов
/ 22 октября 2010

Не думаю, что вы можете ссылаться на псевдоним столбца (в нашем случае это avg_sal) в предложении WHERE.

Вам нужно будет повторить этот внутренний запрос, т. Е .:

SELECT employee_id, salary, department_id,
  (SELECT ROUND(AVG(salary),2)
  FROM employees e_inner
  WHERE e_inner.department_id = e.department_id) AS avg_sal
FROM employees e
WHERE salary > 
 (SELECT ROUND(AVG(salary),2)
  FROM employees e_inner
  WHERE e_inner.department_id = e.department_id)
ORDER BY avg_sal DESC

Не очень хорошо с этими двумя внутренними запросами, но это самый простой способ исправить ошибку.

Обновление: Не проверяли это, но попробуйте следующее:

SELECT e.employee_id, e.salary, e.department_id, b.avg_sal
FROM employees e
INNER JOIN
(SELECT department_id, ROUND(AVG(salary),2) AS avg_sal
 FROM employees
 GROUP BY department_id) e_avg ON e.department_id = e_avg.department_id AND e.salary > e_avg.avg_sal
ORDER BY e_avg.avg_sal DESC
0 голосов
/ 08 июня 2019
select *
from employees e
join(
      select Round(avg(salary)) AvgSal,department_id,department_name as dept_name
      from employees join departments 
      using (department_id)
      group by department_id,department_name
) dd
using(department_id)
where e.salary > dd.AvgSal;

другое решение

select * 
from employees e, 
(
 select 
    department_id, 
    avg(salary) avg_sal 
 from employees 
 group by department_id
) e1
where e.department_id=e1.department_id 
and e.salary > e1.avg_sal
...