mysql - 从2字段开始的平均值,忽略零

时间:2016-03-28 20:15:04

标签: mysql average

我正在寻找一个优雅的查询来获得平均忽略零值。

示例:我有2个值和预期结果:

SELECT X(10,20) AS result
-- expected result: 15

SELECT X(0,20) AS result
-- expected result: 20

SELECT X(10,0) AS result
-- expected result: 10

SELECT X(0,0) AS result
-- expected result: NULL

这是我的尝试:

(val1+val2)/(2-IF(val1,0,1)-IF(val2,0,1))

有更好的方法吗?

谢谢

3 个答案:

答案 0 :(得分:2)

我这样写:

( val1 + val2 )/( ABS(SIGN(val1)) + ABS(SIGN(val2)) )

我相信这相当于OP表达,它已经看起来像没有创建用户定义函数那样优雅。

(这真的只是我个人的偏好,以避免减去常数" 2"和额外的" 1"和#34; 0"常数。)

如果我必须将此表达式扩展为三个参数:

( val1 + val2 + val3)/( ABS(SIGN(val1)) + ABS(SIGN(val2)) + ABS(SIGN(val3)) )

注意:

MySQL SIGN函数将返回一个整数值,表示"符号"数值:-101NULL

MySQL ABS函数将返回一个数字的绝对值,因此将其包围在SIGN函数周围,即ABS(SIGN(n))返回将为01或{ {1}}。 NULL会返回相同的内容。

如果其中一个参数为NULL,则此表达式将返回NULL。就像OP表达式一样。

我不确定那更优雅。但那是我怎么做的。

如果目的是缩短SQL,只需指定SIGN(ABS(n))val1一次,如在OP示例中那样,需要一个函数。 MySQL没有为此提供本机内置函数,因此我们必须定义(创建)用户定义的函数。

但是如果我们这样做,我们需要指定参数的数据类型和返回的数据类型(例如val2BIGINTDECIMAL(M,N)等等。我们采用这种方式,它有可能进行隐式数据类型转换和舍入/不精确。

如果没有用户定义的函数,DOUBLEval1必须在表达式中包含两次。但我认为,在其他一些提议的表达方式中,这比每次的四到五次要好。

答案 1 :(得分:1)

在平均之前,使用CASE来处理其中一列为0的情况。

SELECT CASE
        WHEN val1 = 0 AND val2 = 0 THEN NULL
        WHEN val1 = 0 OR val2 = 0 THEN val1 + val2
        ELSE (val1+val2)/2
       END AS avg

答案 2 :(得分:1)

select case when val1 = 0 and val2= 0 then null
                 when val1 = 0 and val2 ! = 0 then val2
                 when val1 != 0 and val2= 0 then val1
                 else (val1 + val2 ) /2 
               end avg

尝试根据您的要求或mysql版本进行修改