【问题标题】:SQLServer Calculate Average of Multiple ColumnsSQL Server 计算多列的平均值
【发布时间】:2010-09-09 16:23:28
【问题描述】:

我使用 PIVOT 生成了一个表,并且列的输出是动态的。输出之一如下:

user       test1   test2    test3 
--------------------------------
A1          10      20       30  
A2          90      87       75
A3          78      12       34

上表的输出代表参加测试的用户列表。测试将动态添加,因此列本质上是动态的。

现在,我想找出每个用户的平均分以及每个测试的平均分。

我能够计算每个测试的平均值,但对于找出每个用户的平均值感到困惑。

有没有办法做到这一点?

请帮忙。

马赫什

【问题讨论】:

    标签: sql-server average


    【解决方案1】:

    您可以为每个用户添加标记,然后除以列数:

    SELECT
        user, 
        (test1 + test2 + test3) / 3 AS average_mark
    FROM users
    

    或者忽略 NULL 值:

    SELECT
        user,
        (ISNULL(test1, 0) + ISNULL(test2, 0) + ISNULL(test3, 0)) / (
             CASE WHEN test1 IS NULL THEN 0 ELSE 1 END +
             CASE WHEN test2 IS NULL THEN 0 ELSE 1 END +
             CASE WHEN test3 IS NULL THEN 0 ELSE 1 END
        ) AS average_mark
    FROM users
    

    您的表结构有两个缺点:

    • 由于您的表结构是动态创建的,因此您还必须动态构建此查询。
    • 因为有些学生不会参加所有测试,所以可能会有一些 NULL 值。

    您可能需要考虑更改表结构来解决这两个问题。我建议您对表格使用以下结构:

    user   test    mark
    -------------------
    A1     1       10
    A2     1       90
    A3     1       78
    A1     2       20
    A2     2       87
    A3     2       12
    A1     3       30
    A2     3       75
    A3     3       34
    

    然后您可以这样做以获得每个用户的平均分数:

    SELECT user, AVG(mark) AS average_mark
    FROM users
    GROUP BY user
    

    这是为了获得每次测试的平均分:

    SELECT test, AVG(mark) AS average_mark
    FROM users
    GROUP BY test
    

    【讨论】:

    • 感谢您的回复。我的数据也包含 NULL 值,因此按列数取平均值可能会得出错误的结果。
    【解决方案2】:

    您可以在数据源上执行此操作吗?

    【讨论】:

      【解决方案3】:

      简单的答案是UNPIVOT,就像您刚刚 PIVOTed 一样。但最好的答案是一开始就不要做 PIVOT!首先将未透视的数据存储在一个表中,然后从 那个 做你的 PIVOT 和你的平均值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-06
        • 1970-01-01
        • 2015-09-05
        • 1970-01-01
        相关资源
        最近更新 更多