2017-02-14 47 views
0

我有這樣一個數據表彙總:如何基於SQL中的幾個標準

QuestionID UserName UserWeightingForQuestion AnswerGivenForQuestion Metric 
1    A   1.50      1       ToBeCalculated 
1    B   1.00      2       ToBeCalculated 
1    C   1.80      3       ToBeCalculated 
1    D   1.20      1       ToBeCalculated 
1    E   1.40      2       ToBeCalculated 
2    A   1.20      2       ToBeCalculated 
2    B   1.20      2       ToBeCalculated 
2    C   1.10      4       ToBeCalculated 
2    D   1.20      5       ToBeCalculated 
... 

對於每個問題分組,我想填充每個單元下面Metric柱,以計算定義爲值如下所示:

Metric_For_User_A_For_QuestionID_X = SUM(Weights_With_The_Answer_Similar_To_What_Is_Given_By_User_A_In_QuestionID_Group = X)/DISTINCT(All_WEeights_In_One_QuestionID_Group = X) 

具體地說,

Metric_For_User_A_For_QuestionID_1 = SUM(1.50+1.20)/(1.50+1.00+1.80+1.20+1.40) 
Metric_For_User_B_For_QuestionID_1 = SUM(1.00+1.40)/(1.50+1.00+1.80+1.20+1.40) 
Metric_For_User_C_For_QuestionID_1 = SUM(1.80)/(1.50+1.00+1.80+1.20+1.40) 
Metric_For_User_D_For_QuestionID_1 = SUM(1.50+1.20)/(1.50+1.00+1.80+1.20+1.40) 
Metric_For_User_E_For_QuestionID_1 = SUM(1.00+1.40)/(1.50+1.00+1.80+1.20+1.40) 

對於QuestionID組= 2,我想重複上述過程。例如,

Metric_For_User_A_For_QuestionID_2 = SUM(1.20+1.20)/(1.20+1.10) 

我是相當新的SQL,我相信OVER或某種聚合功能可以被用來實現這一目標(?)如果這種計算可以在SQL,可能會有人用SQL專業知識爲我提供了一種實現我想要計算的方法。

原始表格有〜70m行,我正在使用SQL Server。非常感謝您的建議和答案!

+1

你可以嘗試解釋這個邏輯嗎?對於我想要做的事情沒有任何意義。 –

+0

@SeanLange我被朋友問到解決這個問題,所以我不確定他爲什麼要這樣做(我問他同樣的問題)。我試圖自己解決這個問題,但最終意識到,現在已經超越了我的SQL排版,以便高效地完成它。 – user1330974

回答

1

您可以使用SUM窗口函數來執行此操作。

select t.*, 
sum(UserWeightingForQuestion) over(partition by questionID,AnswerGivenForQuestion) 
/sum(UserWeightingForQuestion) over(partition by questionID) as metric 
from tablename t 
  • sum(UserWeightingForQuestion) over(partition by questionID)得到所有UserWeightingForQuestion每questionID總和

  • sum(UserWeightingForQuestion) over(partition by questionID,AnswerGivenForQuestion)總結了每questionID類似UserWeightingForQuestion

編輯:要總結不同權重分母中的每個questionID使用

select t.*, 
sum(UserWeightingForQuestion) over(partition by questionID,AnswerGivenForQuestion) 
/(select sum(distinct UserWeightingForQuestion) from tablename where t.questionID=questionID) as metric 
from tablename t 
+0

正如你所說,你得到了「*每個問題ID *的所有UserWeightingForQuestion的總和」,但OP要求每個問題ID的所有* distinct *權重的總和。 – RBarryYoung

+0

@RBarryYoung ..你是對的。我錯過了那部分。請參閱編輯。 –

+0

@vkp謝謝你的簡潔的答案!這是我需要的。 :) – user1330974

1
declare @quest table(QuestionID int 
        , UserName varchar(20) 
        , UserWeightingForQuestion decimal(10,2) 
        , AnswerGivenForQuestion int); 
insert into @quest values 
(1,'A',1.50,1),(1,'B',1.00,2),(1,'C',1.80,3),(1,'D',1.20,1), 
(1,'E',1.40,2),(2,'A',1.20,2),(2,'B',1.20,2),(2,'C',1.10,4),(2,'D',1.20,5); 

Baicaly你做兩個分區,一個QuestionID和AnswerGivenForQuestion,而另一個由QuestionID。

WITH CALC AS 
(
    SELECT Q2.QuestionID, Q2.UserName, 
      SUM(UserWeightingForQuestion) OVER (PARTITION BY QuestionID, AnswerGivenForQuestion) AS Weight, 
      (SELECT SUM(DISTINCT Q1.UserWeightingForQuestion) 
      FROM @quest Q1 
      WHERE Q1.QuestionID = Q2.QuestionID) AS AllWeights 
    FROM @quest Q2 
) 
SELECT QuestionID, UserName, Weight, AllWeights, 
     CAST(Weight/AllWeights AS DECIMAL(18,2)) as Metric 
FROM CALC 
ORDER BY QuestionID, UserName; 

+------------+----------+--------+------------+--------+ 
| QuestionID | UserName | Weight | AllWeights | Metric | 
+------------+----------+--------+------------+--------+ 
|  1  |  A | 2,70 | 6,90 | 0,39 | 
|  1  |  B | 2,40 | 6,90 | 0,35 | 
|  1  |  C | 1,80 | 6,90 | 0,26 | 
|  1  |  D | 2,70 | 6,90 | 0,39 | 
|  1  |  E | 2,40 | 6,90 | 0,35 | 
+------------+----------+--------+------------+--------+ 
|  2  |  A | 2,40 | 2,30 | 1,04 | 
|  2  |  B | 2,40 | 2,30 | 1,04 | 
|  2  |  C | 1,10 | 2,30 | 0,48 | 
|  2  |  D | 1,20 | 2,30 | 0,52 | 
+------------+----------+--------+------------+--------+ 
+0

你的'AllWeights'列應該總和* distinct *值,而不是所有的值。 – RBarryYoung

+0

@RBarryYoung你是對的,編輯。 – McNets

+0

@McNets非常感謝你的答案寫得非常乾淨(至少在我看來),並且很容易理解。我接受上面提到的vkp提交,因爲他的回答早一點。 – user1330974