我有3张桌子
questions (q_id, q_text)
answers (a_id, a_text, q_id)
correct_answers (q_id, a_id)
答案表每个问题最少可以有1个值,最多可以有4个值
我需要一个纯SQL查询(连接或子查询)才能将下表作为结果
result (q_id, q_text, option1, option2, option3, option4, correct)
option1
,option2
,option3
,option4
都属于答案表,可以是null
,correct
属于{{1}表}
问题:
correct_answers
数目:
q_id q_text
2 Capital of Pakistan is
3 Karachi is in africa
5 New dehli is _____ of india
Correct_answer:
a_id a_text q_id
1 Lahore 2
2 Islamabad 2
3 Karachi 2
4 Quetta 2
5 True 3
6 False 3
7 Capital 5
查询结果:
q_id a_id
2 2
3 6
5 7
答案 0 :(得分:6)
您没有指定RDBMS,但是因为您说PL / SQL我正在猜测Oracle。
根据您的版本,您应该能够使用以下内容 pivot 大多数数据库产品中的数据:
select q_id,
q_text,
max(case when rn = 1 then answer end) Option1,
max(case when rn = 2 then answer end) Option2,
max(case when rn = 3 then answer end) Option3,
max(case when rn = 4 then answer end) Option4,
CorrectAnswer
from
(
select q.q_id,
q.q_text,
a1.a_text Answer,
a2.a_text CorrectAnswer,
row_number() over(partition by q.q_id order by a1.a_id) rn
from questions q
left join answers a1
on q.q_id = a1.q_id
left join Correct_answer ca
on q.q_id = ca.q_id
left join answers a2
on ca.a_id = a2.a_id
)
group by q_id, q_text, CorrectAnswer
order by q_id
如果您使用的是Oracle 11g +,则可以使用PIVOT
功能:
select q_id,
q_text,
Option1, Option2, Option3, Option4,
CorrectAnswer
from
(
select q.q_id,
q.q_text,
a1.a_text Answer,
a2.a_text CorrectAnswer,
row_number() over(partition by q.q_id order by a1.a_id) rn
from questions q
left join answers a1
on q.q_id = a1.q_id
left join Correct_answer ca
on q.q_id = ca.q_id
left join answers a2
on ca.a_id = a2.a_id
)
pivot
(
max(answer)
for rn in ('1' as Option1, '2' as Option2,
'3' as Option3, '4' as Option4)
) piv
order by q_id
答案 1 :(得分:2)
这个适用于ORACLE,MySQL,MS SQL Server和PostgreSQL
SELECT q_id,
q_text,
(SELECT a_text
FROM answers a1
WHERE a1.q_id = q1.q_id
AND (SELECT count(*) FROM answers a2 WHERE a1.q_id = a2.q_id AND a2.a_id < a1.a_id) = 0) as option1,
(SELECT a_text
FROM answers a1
WHERE a1.q_id = q1.q_id
AND (SELECT count(*) FROM answers a2 WHERE a1.q_id = a2.q_id AND a2.a_id < a1.a_id) = 1) as option2,
(SELECT a_text
FROM answers a1
WHERE a1.q_id = q1.q_id
AND (SELECT count(*) FROM answers a2 WHERE a1.q_id = a2.q_id AND a2.a_id < a1.a_id) = 2) as option3,
(SELECT a_text
FROM answers a1
WHERE a1.q_id = q1.q_id
AND (SELECT count(*) FROM answers a2 WHERE a1.q_id = a2.q_id AND a2.a_id < a1.a_id) = 3) as option4,
(SELECT a_text
FROM answers a1
WHERE a1.a_id = (select a_id from correct_answers c1 where c1.q_id = q1.q_id)) as correct
FROM questions q1;
干杯!
答案 2 :(得分:-1)
首先,我要向Position
表添加Answers
列,其中(q_id, Position)
的唯一约束和域约束Position > 0 AND Position <= 4
。无论如何,您可能需要Position
列;通常最好在行有自然顺序时明确排序,而不是试图通过代理键对它们进行排序,或者只是完全丢弃订购信息。
这使您不再像以下那样查询数据库:
SELECT
q.qid, q.q_text,
a1.a_text AS option1, a2.a_text AS option2,
a3.a_text AS option3, a4.a_text AS option4,
ca.a_text AS correct
FROM
Questions q
LEFT JOIN Answers a1 ON a1.q_id = q.q_id AND a1.Position = 1
LEFT JOIN Answers a2 ON a2.q_id = q.q_id AND a2.Position = 2
LEFT JOIN Answers a3 ON a3.q_id = q.q_id AND a3.Position = 3
LEFT JOIN Answers a4 ON a4.q_id = q.q_id AND a4.Position = 4
JOIN Correct_answer qca ON ca.q_id = q.q_id
JOIN Anwsers ca ON ca.a_id = qca.a_id
你可以侥幸成功,因为你有一定数量的可能答案;更通用的解决方案可能需要动态SQL或应用程序层代码来转动结果集。