2013-03-07 44 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(',')