Oracle muestran todos los empleados con más del salario medio de su departamento
Pregunta
Yo escribo una consulta para encontrar empleados que ganan más que el salario promedio dentro de su departamento. Tengo que mostrar la identificación del empleado, el salario, Identificación del departamento, y el salario promedio de ese departamento.
Tengo una consulta que acaba de casi funciona pero sigue dándome "ORA-00904: ': errores AVG_SAL' identificador no válido". Estoy haciendo esto correctamente. ¿Por qué recibo este error identificador no válido?
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
Solución
No creo que pueda referirse a un alias de columna (avg_sal en este caso) en una cláusula WHERE.
Usted tendrá que repetir que consulta interna, es decir:.
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
No es genial, con esas dos consultas internas, pero esa es la manera más sencilla, para corregir el error.
Actualización: ¿No han probado esto, pero intente lo siguiente:
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
Otros consejos
Más eficiente de utilizar la analítica:
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
Se puede volver a escribir como una combinación:
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)
O una subconsulta:
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;
otra solución
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