【问题标题】:What's the most efficient way to get the horizontal average in a MySQL query?在 MySQL 查询中获取水平平均值的最有效方法是什么?
【发布时间】:2010-01-31 22:49:06
【问题描述】:

我有以下 MySQL 表

Id  |  One  |  Two  |  Three
----------------------------
1   |  10   |  30   |  20
2   |  50   |  60   |  20
3   |  60   |  NULL |  40

编辑:当然表不需要默认为NULL,但我不希望它影响平均值(所以平均值计算为50而不是33,33 )。

我希望它看起来像这样,带有 MySQL 查询:

Id | Average
------------
1  | 20
2  | 43,33
3  | 50

实现这一目标的最有效方法是什么?

【问题讨论】:

    标签: sql mysql average


    【解决方案1】:
    select id, (ifnull(one,0) + ifnull(two,0) + ifnull(three,0))/
      ((one is not null) + (two is not null) + (three is not null)) as average from table
    

    【讨论】:

    • 看起来不错,但如果所有 3 都为空,请注意除以零。
    • 修改了我的评论。 select 0/0; 实际上返回 NULL。我不知道......这个答案很完美
    【解决方案2】:

    如果您没有 NULL 值,下面的明显选项会起作用:

    SELECT ((col_1 + col_2 + col_3) / 3) AS Average FROM table;
    

    但是,正如 jxac 在另一个答案中建议的那样,您必须按照以下方式进行操作:

    SELECT id, (ifnull(col_1, 0) + ifnull(col_2, 0) + ifnull(col_3, 0)) /
      ((col_1 is not null) + (col_2 is not null) + (col_3 is not null)) as Average 
    FROM
        table;
    

    如果每列的所有值都为 NULL,则除以零将为该行返回 NULL。

    【讨论】:

    • @Eikern:有什么理由不适合您的问题吗?
    • 这在第三行不起作用:SELECT 60 + NULL + 40 返回NULL。结果也是错误的:60 和 50 的平均值是 50,如示例中,您的查询将返回 33.3(如果它显然不会返回 NULL
    • @Cassy:谢谢。没有注意到 NULL 值。编辑了我的答案以包括 jxac 的替代方案。
    【解决方案3】:

    用途:

      SELECT a.id,
             AVG(a.val) AS average
        FROM (SELECT x.id,
                     x.one AS val
                FROM TABLE x
              UNION ALL
              SELECT y.id,
                     y.two AS val
                FROM TABLE y
              UNION ALL
              SELECT z.id,
                     z.three AS val
                FROM TABLE z) a
    GROUP BY a.id
    

    参考:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多