ユーザーごとにマークを追加してから、列数で割ることができます。
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
テーブル構造には2つの欠点があります。
- テーブル構造は動的に作成されるため、このクエリも動的に作成する必要があります。
- 一部の学生はすべてのテストを受けていないため、いくつかの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