2017-02-15 66 views
0

我正在学习Oracle性能调优,并且对调优查询不太好。任何帮助下面的问题,将不胜感激。提前致谢。在执行汇总时处理外键中的重复数据

我有两个表:

员工

empno deptno sal 
1  10  800 
1  20  800 (Employee 1 works in multiple departments) 
2  10  1000 
3  30  1200 

Department_id department_name 
10    Finance 
20    HR 
30    MANAGER 

现在我想找到每个部门支付的薪金总额。我写了下面的查询,它给出了我需要的结果,但我不确定这个查询在表中可能会有更好的表现,我们可能有数百万条记录和大量重复。

With t as 
(
    select 
     empno, department_id, sal 
    from 
     emp e 
    join 
     departments d on e.deptno = d.department_id 
    order by 
     empno), 
t1 as 
(
    select 
     empno, max(sal)/count(1) salary 
    from 
     t 
    group by 
     empno) 
select 
    department_id, sum(salary) 
from 
    t 
join 
    t1 on t.empno = t1.empno 
group by 
    department_id; 

对于没有使用唯一密钥和PK的员工中的15条记录,查询花费了0.059秒。

感谢

回答

0

如果要通过部门工资总额,那么它的那样简单:

select deptno, sum(sal) 
from employee 
group by deptno 
+0

这会给出错误的结果,因为即使员工1同时为2个部门工作,但他仅由两个部门支付800而不是800支付。 – user7571721

+0

@ user7571721。好。你如何确定哪个部门支付给定员工的工资1.例如,员工1是由部门10还是20支付的? – BobC

+0

说这两个支付一半或只有10个支付..请你帮我解决这两个问题。我只能找出一个查询......当只有10个支付时,不知道如何编写查询。 – user7571721

0

你似乎没有从department选择任何内容,所以目前尚不清楚为什么你需要加入。

要跨部门分配工资,当员工位于多个部门中时,可以在子查询中使用分析函数count()。例如:

with 
    employee (empno, deptno, sal) as ( 
     select 1, 10, 800 from dual union all 
     select 1, 20, 800 from dual union all 
     select 2, 10, 1000 from dual union all 
     select 3, 30, 1200 from dual 
    ), 
    prep (empno, deptno, sal, dept_cnt) as (
     select empno, deptno, sal, count(*) over (partition by empno) 
     from employee 
    ) 
select deptno, sum(sal/dept_cnt) as total_sal 
from  prep 
group by deptno 
order by deptno 
; 

DEPTNO TOTAL_SAL 
------ ---------- 
    10  1400 
    20  400 
    30  1200 
+0

嗨,感谢您的回应,因为我想计算部门明智的月度费用,如果某个部门现在没有任何员工怎么办?那个时候我们需要加入部门表。纠正我,如果我错了? – user7571721