oracle添加,然后avg与null

时间:2013-04-23 13:12:08

标签: sql oracle

我有像:

的sql
select avg(decode(type, 'A', value, null) + decode(type, 'B', value, null)) from table;

这个问题是其中一些类型可能为null,因此添加部分将导致null,因为向null添加任何内容使其为null。所以你可能会认为我可以将解码从null更改为0,但这似乎使得avg()将其视为平均值的一部分,但它不应该/我不希望它被计为平均值的一部分。

理想情况下,添加只会忽略空值,而不是尝试将它们添加到其余值中。

所以让我们说我的数字是:

5 + 6 + 5
3 + 2 + 1
4 + null + 2

它们共计28并且我想要除以8(忽略空值),但是如果我在解码中将空值更改为0,那么平均值将除以9,这不是我想要的。

4 个答案:

答案 0 :(得分:1)

如上所述,您的代码应始终返回null,因为如果第一个decode返回value,则第二个decode必须始终返回null。我会假设您在对代码进行通用化时出错,而您真正想要的是:

avg(decode(type1, 'A', value1, null) + decode(type2, 'B', value2, null))

(或者,代替type1,它可能是a.type。重点是两个解码中的字段应该是单独的字段)


在这种情况下,我认为最简单的方法是首先检查空值:

avg(case when type1 is null and type2 is null then null
    else case type1 when 'A' then value1 else 0 end
       + case type2 when 'B' then value2 else 0 end
    end)

(我将decode替换为case,因为我发现它更容易阅读,但在这种情况下,decode也可以正常工作。)

答案 1 :(得分:0)

一个简单的解决方法是自己计算平均值:

select 
    -- The sum of all values with type 'A' or 'B'
    sum(decode(type, 'A', value, 'B', value, 0)) /
    -- ... divided by the "count" of all values with type 'A' or 'B'
    sum(decode(type, 'A', 1, 'B', 1, 0))
from table;

A SQLFiddle example

但是AVG()的工作方式,如果您只是删除了添加内容并将所有内容放在一个DECODE()

中,那么这可能就足够了
select avg(decode(type, 'A', value, 'B', value, null)) from table

答案 2 :(得分:0)

在这里做一笔总结过于复杂。 Juste用CASE输出值,你就完成了。

SELECT AVG(
    CASE WHEN type = 'A' OR type = 'B' 
    THEN value
    ELSE null
    END
) 
FROM table

答案 3 :(得分:0)

这里的逻辑有点复杂:

select avg((case when type = 'A' then value else 0 end) + (case when type = 'B' then value else 0 end))
from table
where type in ('A', 'B')

where子句保证您至少有一个“A”或“B”。当您没有“A”或“B”的示例时,就会出现问题。