Oracle montrer tous les employés avec plus de salaire moyen de leur département
Question
Je suis en train d'écrire une requête pour trouver des employés qui gagnent plus que le salaire moyen au sein de leur département. Je dois montrer l'ID de l'employé, le salaire, ID du département, et le salaire moyen de ce service.
J'ai une requête qui fonctionne presque, mais il continue à me donner « ORA-00904: « : erreurs AVG_SAL » Identifiant non valide ». Est-ce que je fais cela correctement. Pourquoi est-ce que je reçois cette erreur d'identification non valide?
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
La solution
Je ne crois pas que vous pouvez vous référer à un alias de colonne (avg_sal dans ce cas) dans une clause WHERE.
Vous devrez répéter cette requête intérieure, i.e.:.
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
Pas génial, avec ces deux requêtes internes, mais c'est la façon la plus simple-pour corriger l'erreur.
Mise à jour: ne ai pas testé, mais procédez comme suit:
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
Autres conseils
plus efficace d'utiliser l'analyse:
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
Vous pouvez réécrire comme une jointure:
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)
Ou un sous-requête:
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
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;
Une autre solution
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