【问题标题】:Mysql make AVG return null if any value is null如果任何值为null,Mysql使AVG返回null
【发布时间】:2015-08-17 18:34:18
【问题描述】:

我正在尝试从我在 MySQL 中的一个专栏中获取AVG。但是,如果某些值为null,则必须以另一种方式进行计算。所以,我正在努力做到这一点:

如果销售表中的任何行包含amountNULL,我希望SELECT AVG(amount) from sales 返回NULL。这个可以吗?

【问题讨论】:

  • 你可以在mysql的select中做条件
  • 你能用 PHP 做到这一点吗?
  • 尝试使用 SELECT AVG(IFNULL(amount,0)) from sales。
  • 您的意思是“金额 0”还是“金额 NULL”?零和NULL不一样...
  • 那么在计算平均值时,您希望空值包含在分母中吗?记录 AVG(1,2,3,4, NULL) 会产生 NULL 但您想要的方式是 2 (1+2+3+4+0)=10/5 还是您想要 (1+2+ 3+4)/4=(10/4 还是 2.5)?

标签: mysql average


【解决方案1】:

我会尝试(它将空值视为零):

SELECT AVG(IFNULL(amount,0)) from sales

已编辑(之前误解了问题):

SELECT IF(sum(amount is NULL), NULL, AVG(amount)) from sales

【讨论】:

  • 这会将 Null 计为 ceros,如果任何值为 null,我希望 AVG 的结果为 null。
  • @JavierEnríquez,对不起,更新了答案。
【解决方案2】:

您可以使用以下查询:

SELECT CASE WHEN (SELECT COUNT(*)
                  FROM Sales
                  WHERE amount = 0 OR amount IS NULL) <> 0 
                  THEN NULL 
            ELSE AVG(amount)  END
FROM Sales 

上面使用CASE 表达式中的子查询来检查0NULL 值。如果任意amount 字段的一个值为0NULL,则返回整个平均值为NULL,否则返回amount 的平均值。

Demo here

【讨论】:

  • 我认为是这种方法。问题是,我的查询并不是那么简单。我有加入和一些地方。使用这种方法,我将不得不在子查询中复制查询,这是不可取的。
【解决方案3】:

我确信有几种方法可以做到这一点...这是一种方法。

我使用交叉连接为所有记录返回相同的值,如果该值 > 大于 1,则存在空记录,我使用 case 语句来否定平均值,而是返回空值。这可以在函数调用中轻松完成..

SELECT case when B.c>1 then null else avg(amount) end as myAvg 
FROM Sales 
CROSS JOIN (
  SELECT count(*) c FROM Sales 
  WHERE amount is null) B
GROUP BY  B.C

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 2013-03-22
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    相关资源
    最近更新 更多