2010-10-21 183 views
3

我正在撰寫查詢以查找在其部門中獲得高於平均工資的員工。我需要顯示該部門的員工ID,工資,部門ID和平均工資。Oracle向所有員工顯示其部門工資高於平均水平

我有一個查詢,幾乎可以工作,但它不斷給我「ORA-00904:」AVG_SAL「:無效標識符」錯誤。我是否正確地做這件事。爲什麼我得到這個無效的標識符錯誤?

​​

回答

3

我不相信你可以在WHERE子句中引用列別名(在這種情況下是avg_sal)。

你需要重複內查詢,即:

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 

不是很大,與這兩個內查詢,但是這是糾正錯誤的最簡單方法。

更新:沒有測試過這一點,但嘗試以下操作:

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 
+1

+1:正確 - 列別名不能在WHERE子句中引用。在Oracle中,最早可以引用它們是ORDER BY。 – 2010-10-21 22:26:23

+0

我害怕我不得不暴力強制這個做兩個子查詢。任何想法,爲什麼我不能像這樣引用列別名? – ChrisOPeterson 2010-10-21 22:29:08

+1

爲什麼不使用avg(工資)(部門之間的分配),就像我在下面顯示的那樣? (我不知道爲什麼格式不能很好地顯示。) – RussellH 2010-10-21 22:31:47

3

你可以把它改寫爲連接:

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) 

或子查詢:

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 
+0

第二個是一個非常糟糕的主意,很慢的數據... – 2010-10-21 22:22:52

+0

我不明白爲什麼自我加入是必要的。爲什麼不使用round(avg(薪水))(由department_id分區),2)avg_sal? – RussellH 2010-10-21 22:33:57

+0

@RussellH:子查詢是數據的第二遍,所以除非執行計劃中有一些好的東西,否則你的觀點是沒有意義的。 – 2010-10-21 23:07:48

12

使用分析的效率更高:

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 
+0

+1好主意。您可以格式化1)每行前四個空格; 2)選擇代碼並按下CTRL-K;或3)選擇代碼並點擊代碼按鈕,1010101作爲標籤 – Andomar 2010-10-21 22:37:46

+0

感謝您的提示。 – RussellH 2010-10-21 22:38:46

+0

+1 OP可能一直在尋求理解「引用WHERE子句中的列別名」問題,但這種技術值得高亮顯示。 – 2010-10-21 22:39:25

相關問題