2013-03-19 72 views
0

從另一個問題,我得到這個查詢來獲取我的考試成績總結了正確:SUM與支點來計算總得分

SELECT callSign,event, SUM(score) 
    FROM scores LEFT JOIN candidates 
ON scores.candidateID=candidates.id 
    WHERE candidateID IN 
    (SELECT id 
     FROM candidates 
    WHERE assessmentID='1321') 
    GROUP BY event, callSign 
    ORDER BY candidateID,event 

我得到那個看起來像數據:

callSign event   TotalScore 
Y209 Bridge     45 
Y209 PSA      3 
Y209 Team Analyst Exam  40 
X125 PSA      1 
X125 Team Analyst Exam  38 
V023 Amazing Race Planning 37 

我需要什麼是數據,如:

callSign  Bridge PSA Amazing Race Planning  Team Analyst Exam 
V023        37 
Y209   45  3         40   
X125     1         38   

表結構

`events` 
id event 
1 PSA 
2 Bridge 
30 Stress Board 
25 Amazing Race Planning 
26 Amazing Race Execution 

`scores` 
id candidateID  event   rubric   category       score comment 
1 18  Team Analyst Exam Team Leader Rubric Organizes and Tasks Team Members 3  
2 18  Team Analyst Exam Team Leader Rubric Roles and Responsibilities   5  
3 18  Team Analyst Exam Team Leader Rubric Backward Planning     5  
4 18  Team Analyst Exam Team Leader Rubric Time Management 

`candidates`  
id firstName middleInitial lastName callSign service  rank sex  height weight assessmentID currentlyAssessing hired 

呼號就是X125會由於你正在使用MySQL,以透視數據成列去

+0

看起來像@bluefeet打我給它。 – dnagirl 2013-03-19 14:49:40

+0

你的子查詢是不必要的 – Strawberry 2013-03-19 14:52:47

回答

2

,你將需要使用聚合函數與CASE表達:

SELECT callSign, 
    SUM(case when event = 'Bridge' then score else 0 end) as Bridge, 
    SUM(case when event = 'PSA' then score else 0 end) as PSA, 
    SUM(case when event = 'Amazing Race Planning' then score else 0 end) As AmazingRacePlanning, 
    SUM(case when event = 'Team Analyst Exam' then score else 0 end) as TeamAnalystExam 
FROM scores 
LEFT JOIN candidates 
    ON scores.candidateID=candidates.id 
WHERE candidateID IN (SELECT id 
         FROM candidates 
         WHERE assessmentID='1321') 
GROUP BY callSign 

如果你有數目不詳的events,那麼你將不得不使用準備好的語句來生成動態SQL:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'sum(CASE WHEN event = ''', 
     event, 
     ''' THEN score END) AS `', 
     event, '`' 
    ) 
) INTO @sql 
FROM scores 
LEFT JOIN candidates 
    ON scores.candidateID=candidates.id; 


SET @sql 
    = CONCAT('SELECT callSign, ', @sql, ' 
      FROM scores 
      LEFT JOIN candidates 
       ON scores.candidateID=candidates.id 
      WHERE candidateID IN (SELECT id 
            FROM candidates 
            WHERE assessmentID=''1321'') 
      GROUP BY callSign'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

編輯#1,如果你的events都存儲在一個單獨的表,那麼你可以使用以下方法來生成動態結果:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'sum(CASE WHEN event = ''', 
     event, 
     ''' THEN score END) AS `', 
     event, '`' 
    ) 
) INTO @sql 
FROM events; 



SET @sql 
    = CONCAT('SELECT callSign, ', @sql, ' 
      FROM scores 
      LEFT JOIN candidates 
       ON scores.candidateID=candidates.id 
      WHERE candidateID IN (SELECT id 
            FROM candidates 
            WHERE assessmentID=''1321'') 
      GROUP BY callSign'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

SQL Fiddle with Demo

+0

謝謝,現在如果我有一個名爲'events'的表,那裏有我需要聚合的事件列表? 'SELECT event FROM events ORDER BY id'。我可以在查詢中工作嗎,所以我不需要靜態地添加事件,因爲它們來來去去? – h3rrmiller 2013-03-19 14:49:51

+1

@ h3rrmiller看我的編輯。如果你將有一個未知數的'events',那麼你將需要使用動態sql來生成sql字符串。如果你想用你的表格結構來更新你的OP,那麼我可以告訴你它是如何工作的。 – Taryn 2013-03-19 14:52:50

+0

@ h3rrmiller我看到你用'scores'和'events'表編輯了你的文章,但你沒有包含'candidates'表,你能補充一下嗎? – Taryn 2013-03-19 15:31:21