简体   繁体   English

SELECT查询将表行作为MySQL中的列

[英]SELECT query getting rows of table as columns in MySQL

I have a MySQL database with two tables for questions and answers. 我有一个MySQL数据库,有两个表格用于问答。 Each question has a correct answer and three incorrect answers. 每个问题都有正确的答案和三个不正确的答案。 There are always four answers for every question and only one is correct. 每个问题总有四个答案,只有一个是正确的。

The tables are: 表格是:

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;

I need help with a select query. 我需要一个选择查询的帮助。 I would like to get a table with questions in the rows and the four answers as columns (first the correct one and then the other three). 我希望得到一个表格,其中包含行中的问题和四个答案作为列(首先是正确的,然后是其他三个)。 So far I was able to get an output like this: 到目前为止,我能够得到这样的输出:

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
...

How I can get the following result? 我怎样才能得到以下结果?

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

You can pivot the data by using an aggregate function with a CASE expression. 您可以使用带有CASE表达式的聚合函数来旋转数据。 You can use user-defined variables to implement a row number on each row by question. 您可以使用用户定义的变量逐行实现每行的行号。 Your code will be similar to this: 您的代码与此类似:

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

See SQL Fiddle with Demo . 请参阅SQL Fiddle with Demo This gives the result in separate columns: 这会在单独的列中显示结果:

|   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 |

Constructing a dynamic pivot query for this is a lot of work. 为此构建动态数据透视查询是很多工作。 Instead, what I would probably do is use MySQL's GROUP_CONCAT() aggregate function to create a comma-separated list of the Incorrect_answer fields, while separating out the Correct_Answer as its own column: 相反,我可能会做的是使用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`

The result this produces as received by your application code looks like: 应用程序代码收到的结果如下所示:

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

It then becomes trivial in your application code to split the Incorrect_answers column on the , since it is a comma-separated list. 然后,在您的应用程序代码中分割Incorrect_answers列就变得微不足道,因为它是一个以逗号分隔的列表。

In PHP for example, something like : 例如,在PHP中,类似于:

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

Or in Ruby or Python: 或者在Ruby或Python中:

incorrect = incorrect_answers.split(',')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM