2015-09-07 57 views
0

我有這樣的代碼:發現價值

SELECT username, first_name, last_name, NVL(salary,0) "salary" 
FROM customer 
WHERE NVL(salary,0) < AVG(NVL(salary, 0)); 

試圖找出哪些用戶擁有低於平均工資和一個用戶沒有工資(「零」我必須轉換爲0 )。

最後一句「avg(nvl(salary,0))」不起作用,我不能爲了我的生活找出原因。如果我用一般的實際數字代替陳述,那麼一切正常。

+0

定義「不起作用」。你是否收到錯誤信息 - 如果有,它是什麼?查詢是否運行但提供了錯誤的結果? –

+0

您需要選擇子查詢中的平均值並將此結果與實際工資進行比較 – SomeJavaGuy

+0

我收到此錯誤消息:「00934. 00000 - 」組功能在此處不允許「」 – Mongzyy

回答

2

你可以試着預先選擇的平均水平:

select username,first_name,last_name,nvl(salary,0) "salary" 
from customer 
where nvl(salary,0) < (select avg(nvl(salary,0)) from customer); 

只能在selecthaving條款使用avg,這就是爲什麼你有一個錯誤。

也不要使用nvl,而是使用​​3210來代替,這對大數據來說應該會更快。

+0

非常感謝。完美作品 – Mongzyy

+0

@Shenmoe歡迎您,如果您認爲可以將答案標記爲「已接受」 – smnbbrv

+0

我認爲在這種情況下,您不會看到coalesce和nvl之間存在太大差異,但使用coalesce會是一種好習慣進入未來的使用案例。 –

0
SELECT username,first_name,last_name, NVL(salary,0) "salary" 
FROM customer 
WHERE NVL(salary,0) < (SELECT AVG(NVL(salary,0)) FROM customer); 

這很容易得到。

4

下面是使用分析功能的方法:

select username, 
     first_name, 
     last_name, 
     salary 
from (select username, 
       first_name, 
       last_name, 
       nvl(salary,0) salary, 
       avg(nvl(salary,0)) over() avg_all_salaries 
     from customer) 
where salary < avg_all_salaries 

它可以很容易地也顯示所有薪水的平均值,應該是有史以來出現。

+0

以及我個人認爲這個例子是一個不必要的小查詢爆炸。如果你真的想在稍後使用/顯示'avg',你可以將我的例子中的子查詢重定位到'with'子句並在'customer'表上加入。這有助於避免重複所有字段,就像你在這個例子中看到的一樣 – smnbbrv

+1

這個答案更好,因爲它只需要一次通過表,而不是你的變體與子查詢。性能總是更重要的查詢大小。 – Stawros

+0

在某些版本中,內存管理並不是最佳的分析函數,並且如果在分析函數中進行分區,則可以進入交換區域。不是在這種情況下,但值得記住。 –