Oracle zeigen alle Mitarbeiter mit mehr als durchschnittlichem Gehalt ihrer Abteilung
Frage
Ich schreibe eine Abfrage Mitarbeiter zu finden, die innerhalb ihrer Abteilung größer ist als der durchschnittliche Gehalt verdienen. Ich brauche den Mitarbeiter-ID, Gehalt, Abteilung ID und durchschnittlichen Gehalt dieser Abteilung angezeigt werden soll.
Ich habe eine Abfrage, die nur fast funktioniert, aber es hält mich „ORA-00904:‚Geben AVG_SAL‘: ungültige Kennung“ Fehler. Mache ich das richtig. Warum ich erhalte diese ungültige Kennung Fehler?
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
Lösung
Ich glaube nicht, dass Sie auf eine Spalte Alias ??(avg_sal in diesem Fall) in einer WHERE-Klausel verweisen können.
Sie müssen diese innere Abfrage wiederholen, das heißt:.
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
Nicht so toll, mit diesen beiden inneren Anfragen, aber das ist die am meisten einfache Art und Weise den Fehler zu korrigieren.
Update: habe nicht getestet, aber versuchen Sie Folgendes:
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
Andere Tipps
Effizientere Analysen zu verwenden:
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
Man könnte es umschreiben als Join:
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)
oder eine Unterabfrage:
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;
Eine andere Lösung
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