2010-09-09 144 views
1

我已經使用PIVOT生成了一個表,並且列的輸出是動態的。其中一個輸出如下:SQLServer計算多列的平均值

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

上表的輸出表示參加測試的用戶列表。測試將被動態添加,所以列在本質上是動態的。

現在,我想找出每個用戶的平均分數以及每個測試的平均分數。

我可以計算出每個測試的平均值,但卻不明白每個用戶的平均值。

有沒有辦法做到這一點?

請幫忙。

馬赫什

回答

1

你可以在你的數據源上對它進行透視嗎?

2

您可以添加標記爲每個用戶,然後通過列數除以:

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 
+0

感謝您的回覆。我的數據也包含NULL值,所以按列數取平均值可能會給出錯誤的結果。 – Mahesh 2010-09-09 16:44:02

1

簡單的答案是UNPIVOT就像你剛纔的PIVOTed一樣。但最好的答案是首先不要做PIVOT!首先將未轉移的數據存儲在表中,然後從做你的PIVOT和你的平均值。