2017-02-15 67 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