简体   繁体   English

如何在 MySQL. 中基于外键将两个表中的行组合成一个表?

[英]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 WHENMAX组合。

Working Solution 工作解决方案

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 或以上版本。)

Source 资源

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 .一种方法是使用带有LIMITOFFSET的子查询。

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.

相关问题 MySQL。 如何组合或匹配两个表中的特定行 - MySQL. How to combine or match specifics rows from two tables 如何将通过外键连接的两个表中的所有行迭代到 PHP、CodeIgniter、MySQL 中的单个表中 - How do I iterate all rows from two tables connected by foreign key into a single table in PHP, CodeIgniter, MySQL MYSQL SELECT使用或不使用外键从两个表中获取行 - MYSQL SELECT To fetch rows from two tables with or without a foreign key 从mySQL中的两个表向表添加外键 - Adding a foreign key to a table,from two tables in mySQL 如何从与外键链接的两个表中选择不同的行 - how to select distinct rows from two tables linked with foreign key Mysql的。 如何将带有外键的列的空值插入子表中的行 - Mysql. How to insert row to child table with null value of column that is foreign key 如何合并两个表以从MySQL中的不同表获取结果 - How to combine two tables to get results from different table in MySQL MYSQL:如何根据其他两个表的条​​件在表中插入行 - MYSQL: How to insert rows in a table based on a condition of other two tables 从外键获取价值。 MySQL的。 PHP - Get value from foreign key. MySQL. PHP 根据给定表中的外键查找多个表中的行数 - Find count of rows in multiple tables based on a foreign key in a given table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM