2014-07-19 71 views
0

我有一個查詢,我得到了一些評級 哪些工作正確的平均值。當它等於null時如何讓列輸出爲零?

WITH row_avg_table(avg_rating,employee, approveddate) AS 
(SELECT 
(SELECT AVG(rating) 
FROM (
VALUES (CAST(c.rating1 AS float)), (CAST(c.rating2 AS float)), (CAST(c.rating3 AS float)), 
(CAST(c.rating4 AS float)), (CAST(c.rating5 AS float))) AS v (rating) 
WHERE v.rating > 0) avg_rating, 
employee,approveddate 
FROM CSEReduxResponses c) 
SELECT employee, 
avg(avg_rating) as average_rating 
FROM row_avg_table 
where month(approveddate)=2014 
AND year(approveddate)=6 
GROUP BY employee; 

問題具有即時通訊是當等級1-5將全部爲0。 現在,它給了我「空」我想它顯示爲0這個特殊的日子。 例如,我有以下

create table CSEReduxResponses (rating1 int, rating2 int, rating3 int, rating4 int, rating5 int, 
           approveddate datetime,employee int) 

insert into CSEReduxResponses (rating1 , rating2 ,rating3 , rating4 , rating5 , 
           approveddate, employee) 
values 
(5,4,5,1,4,'2014-06-18',1), 
(5,4,5,1,0,'2014-06-18',1), 
(0,0,0,0,0,'2014-06-19',3); 

所以對於員工= 3 AVERAGE_RATING數據= 0

+0

...你有'null'或'0'嗎?他們不是一回事。 'AVG(...)'會忽略'null',但不會'0'(原因很明顯)。將平均網的平均值與整體平均值的結果不同,那麼您是否想要平均每日平均值,月平均值還是其他?你的結果行應該是什麼樣的? –

回答

0

如果你使用ISNULL功能類似下面

SELECT ISNULL(AVG(rating),some_default_value) 

(OR)CASE條件像下面

SELECT AVG(case when rating = 0 then 1 else rating end) 
0

使用

isnull(Rating1, 0) 

coalesce(Rating1, 0) 

如果Rating1null那麼它會使用默認值0所取代。 Similartly你可以檢查其他領域。該COALESCEISNULL T-SQL函數用於返回輸入參數中的第一個非空的表達,但也有那些之間的一些區別,你可以找到coalesce

0

here

更多的細節,你的問題是在WHERE v.rating > 0條款。如果評分是0,那麼這將不返回任何值 - 並且無法計算任何值的平均值,因此返回null。只需刪除此子句,或者如果要過濾負值,請將其更改爲WHERE v.rating >= 0

如果您使用0來存儲不想影響評分的值(例如您似乎可能會從您提供的第二個示例中完成),那麼這將不起作用 - 您必須而不是去通過輸出和替換0。你可以從你的第一個查詢的結果複製到一個臨時表/表變量的空值和不更換,如

select employee, rating = isnull(t.rating, 0) 
from #temptable t 

或類似的東西。

0

使用CTE沒有優勢。您正在使用交叉應用和值對未標準化的表格進行分類。爲了得到相當於您使用WHERE的unpivot命令...IS NOT NULL,但想必你是確保所有5個值的存在是爲了避免在計算偏差,所以我建議這樣的:

SELECT 
     employee 
    , AVG(isnull(rating,0)) AS avg_rating 
FROM CSEReduxResponses c 
     CROSS APPLY (
      VALUES (CAST(c.rating1 AS float)) 
      , (CAST(c.rating2 AS float)) 
      , (CAST(c.rating3 AS float)) 
      , (CAST(c.rating4 AS float)) 
      , (CAST(c.rating5 AS float)) 
      ) AS ca1 (rating) 
WHERE approveddate >= '20140601' 
     AND approveddate < '20140701' 
GROUP BY 
     employee 
; 

結果從樣本數據:

| EMPLOYEE | AVG_RATING | 
|----------|------------| 
|  1 |  3.4 | 
|  3 |   0 | 

見:http://sqlfiddle.com/#!3/f91d9/2

另外:我會鼓勵你不要在數據上使用函數來促成where條件。避免數據上的函數允許使用索引。這裏所有你需要的是一個簡單的日期範圍(我已經使用YYYYMMDD,因爲它是sql server最安全的格式)。

+0

我認爲這可能更接近OP的需求,但是你需要將'ISNULL'移動到'AVG'的_outside_ - 如果你多次添加'0',你會降低結果,而'AVG'聚合將忽略'null'值(您可能還需要'NULLIF(...)'零到_get_空行...)。請注意,如果可能,最好使用「COALESCE(...)'(而不是'IFNULL(...)')等與db無關的函數。 –

+0

我不確定這是否正確。如果樣本大小爲5(5列未轉化爲5行),並且樣本大小對結果很重要,則AVG()內部的isnull至關重要。實際上,最初我通過在交叉應用中使用where子句排除空值(參見http://sqlfiddle.com/#!3/f91d9/1)以便意識到這種偏見的可能性,從而使用了與unpivot相當的效果。所以我不認爲我們可以確定在沒有更多來自user3591637 –

+0

的輸入的情況下,將isnull放在哪裏,關於coalesce-v-isnull的爭論就是這樣一場辯論。 IFnull適用於MySQL,在這裏不相關。當然,對於那些處理多個dbms的人來說,使用coalesce()是非常有用的。但這不是對與錯的問題。 –

相關問題