SQL多行作为列,不使用PL/SQL

use*_*703 1 sql pivot

我有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)
Run Code Online (Sandbox Code Playgroud)

option1,option2,option3,option4都属于答案表,可以是null,correct属于correct_answers

问题:

q_id  q_text
2     Capital of Pakistan is
3     Karachi is in africa
5     New dehli is _____ of india
Run Code Online (Sandbox Code Playgroud)

回答:

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
Run Code Online (Sandbox Code Playgroud)

正确答案:

q_id  a_id
2     2
3     6
5     7
Run Code Online (Sandbox Code Playgroud)

查询结果:

q_id  q_text                       option_1   option_2   option_3  option_4 correct
2     Capital of Pakistan is       Lahore     Islamabad  Karachi   Quetta   Islamabad
3     Karachi is in africa         True       False      null      null     False
5     New dehli is _____ of india  Capital    Null       Null      Null     Capital
Run Code Online (Sandbox Code Playgroud)

Tar*_*ryn 6

您没有指定RDBMS,但是因为您说PL/SQL我猜Oracle.

根据您的版本,您应该能够使用以下内容来转动大多数数据库产品中的数据:

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
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

如果您使用的是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
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo