2012-07-30 45 views
4

我有一個表sometable:SQL:把一個不同之處在SUM

name |test_date | score 
----------------------- 
jon |2012:07:01| 95 
jon |2012:07:01| 60 
jon |2012:07:01| 30 
alex |2012:07:01| 80 
alex |2012:07:01| 85 
alex |2011:05:01| 40 
emile|2011:01:01| 89  

我想每個名稱一些行,並給了他score_grading與規則的信息: 得分> 79 = A, 80>得分> 49 = B 否則C.

問題是,我想:如果在同一天有一個以上的學生相同的score_grade,比它會計爲一個score_grade。 例如,在上表中我們可以看出,亞歷克斯得到一兩次在一天,我希望它算作只有1 A.

那麼結果將是

name | A | B  | C 
jon | 1 | 1  | 1 
alex | 1 | 0  | 1 
emily| 1 | 0  | 0 

我只知道代碼如:

SELECT name, 
SELECT SUM(IF(score)>79),1,0)) as A, 
SELECT SUM(IF(80>score>49),1,0)) as B, 
SELECT SUM(IF(score)<50),1,0)) as C from sometable group by name 

Nha,我該如何在其上放置「DISTINCT」? 任何人都可以提供解決方案嗎?也許它不需要DISTINCT? 謝謝。 ^^

+2

如果他們在同一天得到不同的分數,例如:一個'C'和一個'A'?同時顯示?顯示一個?哪一個? – 2012-07-30 04:58:02

+0

把他們全部展示出來。同一天只有同一個人的分數算作一個 – user1545296 2012-07-30 05:06:59

回答

2

你的意思是這樣(sqlfiddle)?

SELECT name, SUM(IF(A>=1,1,0)) as A, SUM(IF(B>=1,1,0)) as B, 
    SUM(IF(C>=1,1,0)) as C 
FROM 
(
    SELECT name, test_date, SUM(IF(score>79,1,0)) as A, 
     SUM(IF(score BETWEEN 49 AND 79,1,0)) as B, SUM(IF(score<50,1,0)) as C 
    FROM sometable 
    GROUP BY name, test_date 
) daygroups 
GROUP BY name 

這第一個洗牌的數據放入子查詢的name, test_date, A, B, C行。再查詢外層的聚合將這些行,走1,如果當天是字母等級的至少一個分數,否則取0。


這應該工作太(sqlfiddle):

SELECT name, SUM(IF(lettergrade = 'A',1,0)) AS A, 
    SUM(IF(lettergrade = 'B',1,0)) AS B, SUM(IF(lettergrade = 'C',1,0)) AS C 
FROM 
(
    SELECT DISTINCT name, test_date, 
     CASE WHEN score>79 THEN 'A' 
      WHEN score BETWEEN 49 AND 79 THEN 'B' 
      ELSE 'C' 
     END AS lettergrade 
    FROM sometable 
) lettergrades 
GROUP BY name 

我不確定哪一個會更好。如您在問題中所建議的,此查詢使用DISTINCT。首先它將每個數字等級解析爲相應的字母等級,然後DISTINCT取出重複。最後它將數據轉換爲列。

+0

哇,非常感謝。他們兩個都工作, 我會學習它的邏輯。 ^^ – user1545296 2012-07-30 05:19:39

+0

當然可以。我爲每一個添加了一個解釋,以幫助您瞭解它在做什麼。 – 2012-07-30 05:24:35

0

這應該工作:

SELECT name, 
     SUM(IF(score > 79, 1, 0)) as A, 
     SUM(IF(score BETWEEN 50 AND 79, 1, 0)) as B, 
     SUM(IF(score < 50, 1, 0)) as C 
FROM (SELECT DISTINCT name, score FROM sometable) a 
GROUP BY name; 
+0

我認爲當OP說「不同得分」時,他們是以字母等級表示,不是數字 – 2012-07-30 05:10:09

+0

嗯,謝謝。^^ 但是,不幸的是,扔 名稱| A | B | C jon | 1 | 1 | 1 alex | 2 | 0 | 1 emily | 1 | 0 | 0 – user1545296 2012-07-30 05:15:55

+0

而不是SUM,使用MAX。 – Barmar 2012-07-30 05:21:47