繁体   English   中英

mysql:在一行中多个列的平均值,忽略空值

[英]mysql: Average over multiple columns in one row, ignoring nulls

我有一个大表(站点)有几个数字列 - 比如说a到f。 (这些是来自不同组织的网站排名,例如alexa,google,quantcast等。每个都有不同的范围和格式;它们是来自外部数据库的直接转储。)

对于许多记录,这些列中的一个或多个为空,因为外部DB没有数据。 它们都涵盖了我的数据库的不同子集。

我希望列t是它们的加权平均值(每个a..f都有我赋予的静态权重),忽略空值(可以出现在任何一个中),除非它们全部为空,否则为null。

我更喜欢用简单的SQL计算来做这件事,而不是在应用程序代码中使用它,或者使用一些巨大的丑陋嵌套if块来处理每个空值的排列。 (鉴于我添加了更多的外部数据库源,我的平均列数越来越多,这将是指数级更难看和容易出错的。)

我会使用AVG,但这仅适用于分组,而且这是一个记录中的w /。 数据在语义上可以为空,我不想平均一些“平均”值代替空值; 我想只计算数据所在的列。

有没有办法做到这一点?

理想情况下,我想要的是像UPDATE sites SET t = AVG(a*@a_weight,b*@b_weight,...) ,其中任何空值都被忽略并且没有发生分组。

编辑:我最终使用的是基于van并添加正确的加权平均值(假设a已根据需要进行了规范化,在本例中为0-1(1 =更好):

 UPDATE sites 
 SET t = (@a_weight * IFNULL(a, 0) + ...) / (IF(a IS NULL, 0, @a_weight) + ...) 
 WHERE (IF(a IS NULL, 0, 1) + ...) > 0
UPDATE  sites
        --// TODO: you might need to round it depending on your type
SET     t =(COALESCE(a, 0) +
            COALESCE(b, 0) +
            COALESCE(c, 0) +
            COALESCE(d, 0) +
            COALESCE(e, 0) +
            COALESCE(f, 0)
           ) /
           ((CASE WHEN a IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN b IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN c IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN d IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN e IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN f IS NULL THEN 0 ELSE 1 END CASE)
           )
WHERE   0<>((CASE WHEN a IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN b IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN c IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN d IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN e IS NULL THEN 0 ELSE 1 END CASE) +
            (CASE WHEN f IS NULL THEN 0 ELSE 1 END CASE)
           )

您也可以在其他部分使用COALESCE ,但是当您的值为0时,这将无法处理,因为它将被排除。 WHERE子句避免使用DivideByZero ,但如果条目没有评级,则可能需要有额外的UPDATE语句来处理这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM