2010-03-19 250 views
7

有没有简单的方法可以排除空值影响平均值?他们似乎计为0,这不是我想要的。我只是不想考虑他们的平均值,但这里有一个问题,我不能将它们从结果集中删除,因为该记录有我需要的数据。MySQL:用空值求平均值

更新:

例如:

select avg(col1+col2), count(col3) from table1 
where 
group by SomeArbitraryCol 
having avg(col1+col2) < 500 and count(col3) > 3 
order by avgcol1+col2) asc; 

这是为我工作,但他们都指望着空值0,这是真正摆脱的平均值是不准确整个平均。

+0

什么语言?或者你在SQL中做这些事情吗? – 2010-03-19 21:36:36

+0

简单的SQL下的MySQL – Zombies 2010-03-19 21:38:26

+1

我没有得到它,为什么不选择只有非空值的记录,并平均他们? – questzen 2010-03-19 21:44:20

回答

13

SQL中的聚合函数(SUM,AVG,COUNT等)总是自动排除NULL。

因此SUM(col)/ COUNT(col)= AVG(col) - 这是非常好的一致性。

COUNT(*)的特例是每行计数。

如果您使用NULL来构造表达式:A + B其中A或B为NULL,则A + B将为NULL,而不管其他列为NULL。当存在NULL时,一般来说,AVG(A + B)> AVG(A)+ AVG(B),它们可能也有不同的分母。你必须包装列:AVG(COALESCE(A,0)+ COALESCE(B,0))来解决这个问题,但也许不包括COALESCE(A,0)+ COALESCE(B,0)的情况。

基于您的代码,我建议:

select avg(coalesce(col1, 0) + coalesce(col2, 0)), count(col3) from table1 
where coalesce(col1, col2) is not null -- double nulls are eliminated 
group by SomeArbitraryCol 
having avg(coalesce(col1, 0) + coalesce(col2, 0)) < 500 and count(col3) > 3 
order by avg(coalesce(col1, 0) + coalesce(col2, 0)) asc; 
5
AVG(number) 

是我能想到的最好的方式。这应该自动不包含空值。 Here是一个小小的阅读。根据原来的问题

+0

这对于number1 + number2是否一样?因为我没有那样做,对我来说,空值似乎计为0,因此平均压低了平均值。 – Zombies 2010-03-19 22:36:50

+0

@Zombies不,对于遵循正常NULL规则的手动添加表达式,这是不一样的。 – 2010-03-19 22:44:40

3
SELECT SUM(field)/COUNT(field) 
FROM table 
WHERE othercondition AND (field IS NOT NULL) 

Link

+0

这不会删除字段为空的列吗?尽管如此,我还是需要这个问题的,这就是让这个棘手的问题。 – Zombies 2010-03-19 22:37:27

+1

AVG(col)总是等同于SUM(col)/ COUNT(col),并且NULL会自动排除,所以此查询将始终返回与SELECT AVG(field)FROM table WHERE othercondition相同的结果。 – 2010-03-19 22:46:22

1

答:

SELECT AVG(t1.NumCol + t1.NumCol2), COUNT(table.NumCol) 
FROM 
(
SELECT NumCol, NumCol2 
FROM table 
WHERE (cond) AND (NumCol IS NOT NULL) AND (NumCol2 IS NOT NULL) 
) t1, 
table 
WHERE (cond) 

我认为新的限制,这仍然工作在理论,但不是最有效的方式

1

有一个很好的机会,你就可以得到从别人已经在这里说了正确的答案,但如果你没有:

表中的哪些值可能为NULL?如果它们中的任何一个是,你想要发生什么?

你永远不指定你想看到什么样的结果,如果COL1为NULL,或COL2是NULL,或者如果他们既发生为NULL等

0

我最近使用这一招:

AVG(
    CASE 
     WHEN 
      valToBeAveraged IS NULL 
     THEN 
      0 
     ELSE 
      valToBeAveraged 
    END 
) 

我相信警告就是这样。但是这让我放心,因为我确切知道它是如何工作的。

快乐编码