2

我有像这样的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(忽略 null),但是如果我在解码中将 null 更改为 0,则 avg 将除以 9,这不是我想要的。

4

4 回答 4

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)

(我替换decodecase因为我发现它更容易阅读,但是在这种情况下decode也可以。)

于 2013-04-23T13:22:48.063 回答
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;

SQLFiddle示例

但是这种方式AVG()可行,如果您只是删除添加并将所有内容放在一个单一的,它可能就足够了DECODE()

select avg(decode(type, 'A', value, 'B', value, null)) from table
于 2013-04-23T13:14:39.377 回答
0

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

SELECT AVG(
    CASE WHEN type = 'A' OR type = 'B' 
    THEN value
    ELSE null
    END
) 
FROM table
于 2013-04-23T13:15:21.820 回答
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”的示例时,就会出现问题。

于 2013-04-23T13:23:52.193 回答