相关子查询,以查找在其部门中获得超过平均工资的员工

时间:2015-08-19 13:48:34

标签: sql oracle subquery correlated-subquery

我正在编写Oracle查询,以查找收入高于其部门内平均工资的员工。我需要显示该部门的last_name,employee_ID,salary,department_id和平均工资。我写了这个查询,但我得不到想要的答案。可以请有人告诉我,我在哪里犯错误

select last_name,employee_id,salary,department_id,avg(salary) 
  from employees e1
 where salary > (select avg(salary) 
                   from employees e2 
                  where e1.department_id=e2.department_id)
 group by last_name,employee_id,salary,department_id

2 个答案:

答案 0 :(得分:0)

with med as
         (select department_id, avg(salary) avgSalary
            from employees
           group by department_id)
        select last_name, employee_id, salary, e.department_id, avgSalary
          from employees e, med m
         where e.department_id = m.department_id and e.salary > m.avgSalary

答案 1 :(得分:0)

如果您需要在结果中显示平均部门薪水,则无法找到相关的子查询。

您可以在单独的查询中计算平均工资,然后加入其中:

with emp as (select 1 emp_id, 'bob' name, 10000 salary, 1 dept_id from dual union all
             select 2 emp_id, 'joe' name, 20000 salary, 1 dept_id from dual union all
             select 3 emp_id, 'fred' name, 10000 salary, 2 dept_id from dual union all
             select 4 emp_id, 'ivy' name, 20000 salary, 2 dept_id from dual union all
             select 5 emp_id, 'ann' name, 30000 salary, 2 dept_id from dual union all
             select 6 emp_id, 'jo' name, 20000 salary, 3 dept_id from dual union all
             select 7 emp_id, 'fion' name, 30000 salary, 3 dept_id from dual union all
             select 8 emp_id, 'alan' name, 40000 salary, 3 dept_id from dual union all
             select 9 emp_id, 'eve' name, 50000 salary, 3 dept_id from dual union all
             select 10 emp_id, 'rob' name, 10000 salary, 4 dept_id from dual)
select emp1.name,
       emp1.emp_id,
       emp1.salary,
       emp1.dept_id,
       emp2.average_dept_salary
from   emp emp1
       inner join (select dept_id,
                          avg(salary) average_dept_salary
                   from   emp
                   group by dept_id) emp2
           on (emp1.dept_id = emp2.dept_id)
where emp1.salary > emp2.average_dept_salary;

NAME     EMP_ID     SALARY    DEPT_ID AVERAGE_DEPT_SALARY
---- ---------- ---------- ---------- -------------------
joe           2      20000          1               15000
ann           5      30000          2               20000
alan          8      40000          3               35000
eve           9      50000          3               35000

但就个人而言,我会使用分析函数来获得平均工资,然后使用它进行过滤。这样,您不必扫描表格两次:

with emp as (select 1 emp_id, 'bob' name, 10000 salary, 1 dept_id from dual union all
             select 2 emp_id, 'joe' name, 20000 salary, 1 dept_id from dual union all
             select 3 emp_id, 'fred' name, 10000 salary, 2 dept_id from dual union all
             select 4 emp_id, 'ivy' name, 20000 salary, 2 dept_id from dual union all
             select 5 emp_id, 'ann' name, 30000 salary, 2 dept_id from dual union all
             select 6 emp_id, 'jo' name, 20000 salary, 3 dept_id from dual union all
             select 7 emp_id, 'fion' name, 30000 salary, 3 dept_id from dual union all
             select 8 emp_id, 'alan' name, 40000 salary, 3 dept_id from dual union all
             select 9 emp_id, 'eve' name, 50000 salary, 3 dept_id from dual union all
             select 10 emp_id, 'rob' name, 10000 salary, 4 dept_id from dual),
     res as (select name,
                    emp_id,
                    salary,
                    dept_id,
                    avg(salary) over (partition by dept_id) average_dept_salary
             from   emp)
select name,
       emp_id,
       salary,
       dept_id,
       average_dept_salary
from   res
where  salary > average_dept_salary;

NAME     EMP_ID     SALARY    DEPT_ID AVERAGE_DEPT_SALARY
---- ---------- ---------- ---------- -------------------
joe           2      20000          1               15000
ann           5      30000          2               20000
alan          8      40000          3               35000
eve           9      50000          3               35000

这是一种你可以通过相关查询(实际上是两个)做你想要的方式,但我真的,真的会建议不要使用它。首先,现在有3张同桌的传递!

with emp as (select 1 emp_id, 'bob' name, 10000 salary, 1 dept_id from dual union all
             select 2 emp_id, 'joe' name, 20000 salary, 1 dept_id from dual union all
             select 3 emp_id, 'fred' name, 10000 salary, 2 dept_id from dual union all
             select 4 emp_id, 'ivy' name, 20000 salary, 2 dept_id from dual union all
             select 5 emp_id, 'ann' name, 30000 salary, 2 dept_id from dual union all
             select 6 emp_id, 'jo' name, 20000 salary, 3 dept_id from dual union all
             select 7 emp_id, 'fion' name, 30000 salary, 3 dept_id from dual union all
             select 8 emp_id, 'alan' name, 40000 salary, 3 dept_id from dual union all
             select 9 emp_id, 'eve' name, 50000 salary, 3 dept_id from dual union all
             select 10 emp_id, 'rob' name, 10000 salary, 4 dept_id from dual)
select emp1.name,
       emp1.emp_id,
       emp1.salary,
       emp1.dept_id,
       (select avg(salary) 
        from   emp emp3
        where  emp1.dept_id = emp3.dept_id) average_dept_salary
from   emp emp1
where  emp1.salary > (select avg(salary) 
                      from   emp emp2
                      where  emp1.dept_id = emp2.dept_id);

NAME     EMP_ID     SALARY    DEPT_ID AVERAGE_DEPT_SALARY
---- ---------- ---------- ---------- -------------------
joe           2      20000          1               15000
ann           5      30000          2               20000
alan          8      40000          3               35000
eve           9      50000          3               35000