2013-03-07 64 views
1

我有一個MySQL數據庫,其中有兩個表格用於提問和回答。每個問題都有正確的答案和三個不正確的答案。每個問題總是有四個答案,只有一個是正確的。SELECT查詢在MySQL中獲取作爲列的表的行數

的表是:

CREATE TABLE `question` (
    `id_question` smallint(5) unsigned NOT NULL auto_increment, 
    `text` varchar(255) collate utf8_unicode_ci default NULL, 
    PRIMARY KEY (`id_question`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 


CREATE TABLE `answer` (
    `id_answer` mediumint(8) unsigned NOT NULL auto_increment, 
    `id_question` smallint(5) unsigned NOT NULL, 
    `is_correct` tinyint(1) NOT NULL, 
    `text` varchar(45) collate utf8_unicode_ci default NULL, 
    PRIMARY KEY (`id_answer`,`id_question`), 
    KEY `fk_id_question_idx` (`id_question`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

我需要一個選擇查詢的幫助。我想在行中得到一個問題表,並將四個答案作爲列(首先是正確的,然後是其他三個)。到目前爲止,我能夠得到這樣的輸出:

Question | Answer | Is_Correct 
------------------------------- 
Question 1 Answer 1-1 1 
Question 1 Answer 1-2 0 
Question 1 Answer 1-3 0 
Question 1 Answer 1-4 0 
Question 2 Answer 2-1 1 
Question 2 Answer 2-2 0 
Question 2 Answer 2-3 0 
Question 2 Answer 2-4 0 
... 

我如何得到以下結果?

Question | Correct_Answer | Incorrect_answer1 | Incorrect_answer2 | Incorrect_answer3 
-------------------------------------------------------------- 
Question 1 Answer 1-1 Answer 1-2 Answer 1-3 Answer 1-4 
Question 2 Answer 2-1 Answer 2-2 Answer 2-3 Answer 2-4 
+0

我不熟悉在MySQL中的樞軸查詢,但這是一個開始googling :)的好地方。希望我能幫到更多...我確信有人會發布答案。 – 2013-03-07 19:33:49

回答

2

您可以樞軸通過使用聚集函數與CASE表達的數據。您可以使用用戶定義的變量按問題在每一行上實施行號。您的代碼將與此類似:

select q.text Question, 
    max(case when a.is_correct = 1 then a.text end) Correct_answer, 
    max(case when a.is_correct = 0 and rn=1 then a.text end) Incorrect_Answer1, 
    max(case when a.is_correct = 0 and rn=2 then a.text end) Incorrect_Answer2, 
    max(case when a.is_correct = 0 and rn=3 then a.text end) Incorrect_Answer3 
from question q 
inner join 
(
    select a.id_question, 
    a.text, 
    a.is_correct, 
    a.id_answer, 
    @row:=case 
      when @prevQ=id_question 
       and is_correct = 0 
      then @row +1 
      else 0 end rn, 
    @prevA:=id_answer, 
    @prevQ:=id_question 
    from answer a 
    cross join (select @row:=0, @prevA:=0, @prevQ:=0)r 
    order by a.id_question, a.id_answer 
) a 
    on q.id_question = a.id_question 
group by q.text 
order by a.id_question, a.id_answer 

請參閱SQL Fiddle with Demo。這給出了單獨的列結果:

| QUESTION | CORRECT_ANSWER | INCORRECT_ANSWER1 | INCORRECT_ANSWER2 | INCORRECT_ANSWER3 | 
------------------------------------------------------------------------------------------- 
| Question 1 |  Answer 1-1 |  Answer 1-2 |  Answer 1-3 |  Answer 1-4 | 
| Question 2 |  Answer 2-1 |  Answer 2-2 |  Answer 2-3 |  Answer 2-4 | 
1

構建一個動態數據透視查詢是很多工作。相反,我可能會做的是使用MySQL的GROUP_CONCAT()聚合函數創建一個逗號分隔的Incorrect_answer字段列表,而分離出Correct_Answer作爲自己的列:

SELECT 
    question.`text`, 
    /* Separate the one where Is_Correct = 1 and discard the others with a MAX() aggregate */ 
    MAX(CASE WHEN Is_Correct = 1 THEN answer.`text` ELSE NULL END) AS Correct_Answer, 
    /* Group the rows where Is_Correct = 0 into a comma-separated list */ 
    GROUP_CONCAT(CASE WHEN Is_Correct = 0 THEN answer.`text` ELSE NULL END) AS Incorrect_answers 
FROM 
    question 
    JOIN answer ON question.id_question = answer.id_question 
GROUP BY Question.`text` 

這會產生你所收到的結果應用程序的代碼如下所示:

Question  Correct_Answer Incorrect_answers 
-------------------------------------------------------------- 
Question 1 Answer 1-1 Answer 1-2,Answer 1-3,Answer 1-4 
Question 2 Answer 2-1 Answer 2-2,Answer 2-3,Answer 2-4 

然後它變成你的應用程序代碼,以分割的,Incorrect_answers列,因爲它是一個逗號分隔的列表微不足道。

在PHP例如,是這樣的:

$incorrect = explode(',', $row['Incorrect_answers']); 

或者在Ruby或Python:

incorrect = incorrect_answers.split(',')