问题描述
我在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 是链接两个表的字段。 每个Q_id都有恰好3个选项作为答案。
现在,我想在MysqL中编写一个查询,该查询给出下表作为输出。
+------+--------------------+----------+----------+----------+
| Q_ID | Question |Answer 1 |Answer 2 |Answer 3 |
+------+--------------------+----------+----------+----------+
| 1 | Colors in Rainbow |Violet |Blue |Yellow |
| 2 | Colors in Tree |brown |Orange |Green |
+------+--------------------+----------+----------+----------+
我该怎么做??
解决方法
如果是所有情况,则可以在此处使用简单的CASE WHEN
和MAX
组合。
SELECT Q_ID,QUESTION,MAX(CASE WHEN MOD(ID,3)=1 THEN ANSWER END) AS ANS1,3)=2 THEN ANSWER END) AS ANS2,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,'Violet' AS ANSWER UNION ALL
SELECT 2 AS ID,'Blue ' AS ANSWER UNION ALL
SELECT 3 AS ID,'Yellow' AS ANSWER UNION ALL
SELECT 4 AS ID,'Brown ' AS ANSWER UNION ALL
SELECT 5 AS ID,'Orange' AS ANSWER UNION ALL
SELECT 6 AS 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
编辑:
正如stickybit所说,我的第一个答案有一个缺陷。为了消除此缺陷,我使用了ROW_NUMBER
。该编辑是根据stickybit的指导进行的。感谢您的建议。 (窗口功能仅适用于mysql 8.0或更高版本。)
SELECT Q_ID,MAX(CASE WHEN MOD(RN,'Violet' AS ANSWER UNION ALL
SELECT 4 AS ID,'Blue' AS ANSWER UNION ALL
SELECT 7 AS ID,'Yellow' AS ANSWER UNION ALL
SELECT 10 AS ID,'Brown' AS ANSWER UNION ALL
SELECT 13 AS ID,'Orange' AS ANSWER UNION ALL
SELECT 16 AS ID,'Green' AS ANSWER
)
SELECT row_number() OVER (PARTITION BY TAB1.Q_ID ORDER BY TAB2.ID) as rn,TAB2.ID,QUESTION
,
一种方法是对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
请注意,您需要在此处ORDER BY
的某些列,否则将无法保证顺序,这可能导致某些答案出现多次或根本不出现。
使用表group_concat()
中的answers
按照正确的顺序排列答案,然后加入questions
,在其中使用substring_index()
进行拆分:
select q.q_id,q.question,substring_index(all_answers,',1) Answer1,substring_index(substring_index(all_answers,-2),1) Answer2,-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
我使用','
作为连接答案的分隔符。
请参见demo。
如果答案中可能存在','
,则可以通过在separator '@'
中添加说group_concat()
并使用'@'
将其更改为任何其他字符在substring_index()
中。
请参见demo。
结果:
| q_id | question | Answer1 | Answer2 | Answer3 |
| ---- | ----------------- | ------- | ------- | ------- |
| 1 | Colors in Rainbow | Violet | Blue | Yellow |
| 2 | Colors in Tree | Brown | Orange | Green |