Sql server SQLServer计算多个列的平均值

Sql server SQLServer计算多个列的平均值,sql-server,average,Sql Server,Average,我使用PIVOT生成了一个表,列的输出是动态的。其中一个输出如下所示: user test1 test2 test3 -------------------------------- A1 10 20 30 A2 90 87 75 A3 78 12 34 上表的输出表示参加测试的用户列表。测试将动态添加,因此列本质上是动态的 现在,我想找出每个用户

我使用PIVOT生成了一个表,列的输出是动态的。其中一个输出如下所示:

user       test1   test2    test3 
--------------------------------
A1          10      20       30  
A2          90      87       75
A3          78      12       34
上表的输出表示参加测试的用户列表。测试将动态添加,因此列本质上是动态的

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

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

有没有办法做到这一点

请帮忙


Mahesh

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

SELECT
    user, 
    (test1 + test2 + test3) / 3 AS average_mark
FROM users
或忽略空值:

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
您的表结构有两个缺点:

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

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

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

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

SELECT
    user, 
    (test1 + test2 + test3) / 3 AS average_mark
FROM users
或忽略空值:

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
您的表结构有两个缺点:

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

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

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

你能在数据源上做这件事吗?你能在数据源上做这件事吗。但最好的答案是一开始就不要做支点!首先将未插入的数据存储在一个表中,然后从该表中进行数据透视和平均值。

简单的答案与刚才的数据透视相同。但最好的答案是一开始就不要做支点!首先将未插入的数据存储在表中,然后再从表中存储数据透视和平均值。

谢谢您的回复。我的数据也包含空值,所以按列数取平均值可能会给出错误的结果。谢谢你的回复。我的数据也包含空值,因此按列数取平均值可能会给出错误的结果。