[英]How to combine rows from two tables into a single table based on Foreign key, in MySQL.?
I have 2 tables in MySQL as shown below:我在 MySQL 中有 2 个表,如下所示:
+------+-------+------------------+
| 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. Q_Id是链接两个表的字段。 Each Q_id has exactly 3 options as answers.每个 Q_id恰好有 3 个选项作为答案。
Now, I want to write a query in MySQL that gives the following table as output .现在,我想在 MySQL 中编写一个查询,将下表提供为 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.如果它们都是这种情况,那么您可以在这里使用简单的CASE WHEN
和MAX
组合。
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.正如stickybit所说,我的第一个答案存在缺陷。 For getting rid of this flaw i used ROW_NUMBER
.为了摆脱这个缺陷,我使用了ROW_NUMBER
。 This edit made by guidance that come from stickybit.此编辑由来自stickybit 的指导进行。 Thank you for your advice.感谢您的意见。 (Window functions are work only mysql version 8.0 or above.) (窗口功能仅适用于 mysql 8.0 或以上版本。)
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
.一种方法是使用带有LIMIT
和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 db<>小提琴
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.请注意,您需要在此处ORDER BY
一些列,否则无法保证顺序,这可能导致某些答案出现多次或根本不出现。
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:在表answers
中使用group_concat()
以正确顺序连接questions
,然后加入使用substring_index()
拆分的问题:
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()
.如果答案中可能存在','
那么您可以通过在group_concat()
中添加separator '@'
并在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 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.