2013-07-02 4 views
22

列のAVGを得るには、NULLとゼロの値を無視しますか?ヌルまたはゼロの値を無視してAVGを取得する

私はそれらの平均を得るために3つの列を持っているが、私は次のスクリプトを使用しよう:

SELECT distinct 
    AVG(cast(ISNULL(a.SecurityW,0) as bigint)) as Average1 
    ,AVG(cast(ISNULL(a.TransferW,0) as bigint)) as Average2 
    ,AVG(cast(ISNULL(a.StaffW,0) as bigint)) as Average3 
FROM Table1 a, Table2 b 
WHERE a.SecurityW <> 0 AND a.SecurityW IS NOT NULL 
AND a.TransferW<> 0 AND a.TransferWIS NOT NULL 
AND a.StaffW<> 0 AND a.StaffWIS NOT NULL 
AND MONTH(a.ActualTime) = 4 
AND YEAR(a.ActualTime) = 2013 

私はどんな結果を得ることはありません、しかし、3つの列がNULLとゼロを含む値を持っています!

平均値を取得する前にヌル値を除外する方法はありますか?

例:AVERAGE(NOTNULL(SecurityW))

+1

を使用しています。また、 'Column <> 0'は' Column'が 'NULL'の場合に' UNKNOWN'と評価されるので、 'NOT NULL'チェックは不要です。 –

答えて

1

あなたは既にNOT NULLNULL値をフィルタリングすることを試みています。 WHERE節でこれをIS NOT NULLに変更して実行します。 AVGメソッドのISNULL関数を削除して、これをリファクタリングすることができます。また、実際にbigintが必要になるとは思わないので、キャストを取り除くことができます。

SELECT distinct 
    AVG(a.SecurityW) as Average1 
    ,AVG(a.TransferW) as Average2 
    ,AVG(a.StaffW) as Average3 
FROM Table1 a, Table2 b 
WHERE a.SecurityW <> 0 AND a.SecurityW IS NOT NULL 
AND a.TransferW<> 0 AND a.TransferWIS IS NOT NULL 
AND a.StaffW<> 0 AND a.StaffWIS IS NOT NULL 
AND MONTH(a.ActualTime) = 4 
AND YEAR(a.ActualTime) = 2013 
7

これはうまくいくはずですが、試してみません。これはゼロを除外します。 NULLは

AVG (CASE WHEN SecurityW <> 0 THEN SecurityW ELSE NULL END) 
43

NULLデフォルトで除外されますがNULL0をオンにするNULLIFを使用できるように、すでに無視されます。また、にDISTINCTWHEREは必要ありません。

SELECT AVG(cast(NULLIF(a.SecurityW, 0) AS BIGINT)) AS Average1, 
     AVG(cast(NULLIF(a.TransferW, 0) AS BIGINT)) AS Average2, 
     AVG(cast(NULLIF(a.StaffW, 0) AS BIGINT)) AS Average3 
FROM Table1 a 
WHERE a.ActualTime >= '20130401' 
     AND a.ActualTime < '20130501' 

PS私はそれはとても私の答えからそれを省略しているの結合条件をなしているとのために元のクエリにあるものTable2 b見当がつかない。

+0

btw整数をbigintに変換することによって何かが起こるとは思わない。 –

+5

@ t-clausen.dk - 'SUM'が大きすぎると算術オーバーフローエラーを防ぐことができる。 SELECT(SELECT 2147483647 UNION ALL SELECT 2147483647)T(C) 'は失敗しますが、' SELECT AVG(CAST(C AS BIGINT))FROM(SELECT 2147483647 UNION ALL SELECT 2147483647)T(C) 'は成功します。 –

+0

あなたのポイント –

2

は私のために働いていた:平均関数内の '0' または 'NULL' を考慮しない場合の

AVG(CASE WHEN SecurityW <> 0 THEN SecurityW ELSE NULL END) 
0

を。 は、単純にすべてのものを `AND`sは、あなただけのすべての3列に非NULL値を持つ行を取得しますことを意味

AVG(NULLIF(your_column_name,0)) 
関連する問題