I have 2 tables in MySQL as shown below:
+------+-------+------------------+
| ID | Q_ID |Question |
+------+-------+------------------+
|1 | 1 |Colors in Rainbow |
|2 | 2 |Colors in Tree |
+------+-------+------------------+
+------+-------+--------+
| ID | Q_ID |Answer |
+------+-------+--------+
|1 | 1 |Violet |
|2 | 1 |Blue |
|3 | 1 |Yellow |
|4 | 2 |Brown |
|5 | 2 |Orange |
|6 | 2 |Green |
+------+-------+--------+
Q_Id is the field linking the two tables. Each Q_id has exactly 3 options as answers.
Now, I want to write a query in MySQL that gives the following table as output .
+------+--------------------+----------+----------+----------+
| Q_ID | Question |Answer 1 |Answer 2 |Answer 3 |
+------+--------------------+----------+----------+----------+
| 1 | Colors in Rainbow |Violet |Blue |Yellow |
| 2 | Colors in Tree |Brown |Orange |Green |
+------+--------------------+----------+----------+----------+
How do I do that.?
If they are all of the cases then you can use simple CASE WHEN
and MAX
combination here.
SELECT Q_ID ,QUESTION,
MAX(CASE WHEN MOD(ID,3)=1 THEN ANSWER END) AS ANS1,
MAX(CASE WHEN MOD(ID,3)=2 THEN ANSWER END) AS ANS2,
MAX(CASE WHEN MOD(ID,3)=0 THEN ANSWER END) AS ANS3
FROM
(WITH TAB1 AS
(
SELECT 1 AS ID, 1 AS Q_ID , 'Colors in Rainbow' AS QUESTION UNION ALL
SELECT 2 AS ID, 2 AS Q_ID , 'Colors in Tree' AS QUESTION
),
TAB2 AS (
SELECT 1 AS ID , 1 AS Q_ID, 'Violet' AS ANSWER UNION ALL
SELECT 2 AS ID , 1 AS Q_ID, 'Blue ' AS ANSWER UNION ALL
SELECT 3 AS ID , 1 AS Q_ID, 'Yellow' AS ANSWER UNION ALL
SELECT 4 AS ID , 2 AS Q_ID, 'Brown ' AS ANSWER UNION ALL
SELECT 5 AS ID , 2 AS Q_ID, 'Orange' AS ANSWER UNION ALL
SELECT 6 AS ID , 2 AS Q_ID, 'Green ' AS ANSWER
)
SELECT TAB2.ID,TAB1.Q_ID,TAB1.QUESTION,TAB2.ANSWER FROM TAB1 INNER JOIN TAB2 ON TAB2.Q_ID=TAB1.Q_ID
) A
GROUP BY Q_ID ,QUESTION
Edit:
As stickybit said there is a flaw in my first answer. For getting rid of this flaw i used ROW_NUMBER
. This edit made by guidance that come from stickybit. Thank you for your advice. (Window functions are work only mysql version 8.0 or above.)
SELECT Q_ID ,QUESTION,
MAX(CASE WHEN MOD(RN,3)=1 THEN ANSWER END) AS ANS1,
MAX(CASE WHEN MOD(RN,3)=2 THEN ANSWER END) AS ANS2,
MAX(CASE WHEN MOD(RN,3)=0 THEN ANSWER END) AS ANS3
FROM
(WITH TAB1 AS
(
SELECT 1 AS ID, 1 AS Q_ID , 'Colors in Rainbow' AS QUESTION UNION ALL
SELECT 2 AS ID, 2 AS Q_ID , 'Colors in Tree' AS QUESTION
),
TAB2 AS (
SELECT 1 AS ID , 1 AS Q_ID, 'Violet' AS ANSWER UNION ALL
SELECT 4 AS ID , 1 AS Q_ID, 'Blue' AS ANSWER UNION ALL
SELECT 7 AS ID , 1 AS Q_ID, 'Yellow' AS ANSWER UNION ALL
SELECT 10 AS ID , 2 AS Q_ID, 'Brown' AS ANSWER UNION ALL
SELECT 13 AS ID , 2 AS Q_ID, 'Orange' AS ANSWER UNION ALL
SELECT 16 AS ID , 2 AS Q_ID, 'Green' AS ANSWER
)
SELECT row_number() OVER (PARTITION BY TAB1.Q_ID ORDER BY TAB2.ID) as rn, TAB2.ID,TAB1.Q_ID,TAB1.QUESTION,TAB2.ANSWER FROM TAB1 INNER JOIN TAB2 ON TAB2.Q_ID=TAB1.Q_ID
) A
GROUP BY Q_ID ,QUESTION
One way is to use subqueries with LIMIT
and OFFSET
.
SELECT t1.q_id,
(SELECT t2.answer
FROM elbat2 t2
WHERE t2.q_id = t1.q_id
ORDER BY t2.id
LIMIT 1
OFFSET 0) answer1,
(SELECT t2.answer
FROM elbat2 t2
WHERE t2.q_id = t1.q_id
ORDER BY t2.id
LIMIT 1
OFFSET 1) answer2,
(SELECT t2.answer
FROM elbat2 t2
WHERE t2.q_id = t1.q_id
ORDER BY t2.id
LIMIT 1
OFFSET 2) answer3
FROM elbat1 t1;
db<>fiddle
Note that you need some column(s) to ORDER BY
here as otherwise there is no guaranteed order which could lead to some answer show up more than once or not at all.
Use group_concat()
in the table answers
to concat the answers in the correct order and then join to questions
where you use substring_index()
to split:
select q.q_id, q.question,
substring_index(all_answers, ',', 1) Answer1,
substring_index(substring_index(all_answers, ',', -2), ',', 1) Answer2,
substring_index(all_answers, ',', -1) Answer3
from questions q inner join (
select q_id, group_concat(answer order by id) all_answers
from answers
group by q_id
) a
on a.q_id = q.q_id
I use ','
as the separator for the concatenated answers.
See the demo .
If there is a case that ','
could exist inside an answer then you can change it to any other character, by adding say separator '@'
in group_concat()
and using '@'
in substring_index()
.
See the demo .
Results:
| q_id | question | Answer1 | Answer2 | Answer3 |
| ---- | ----------------- | ------- | ------- | ------- |
| 1 | Colors in Rainbow | Violet | Blue | Yellow |
| 2 | Colors in Tree | Brown | Orange | Green |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.