1

私は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、テーブルに属することができますoption3option4nullcorrectcorrect_answers

質問:

q_id  q_text
2     Capital of Pakistan is
3     Karachi is in africa
5     New dehli is _____ of india

回答:

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

クエリの結果:

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
4

3 に答える 3

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

SQL FiddlewithDemoを参照してください。

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

SQL FiddlewithDemoを参照してください

于 2013-02-28T20:16:32.753 に答える
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;

乾杯!

于 2013-02-28T20:51:04.227 に答える
-1

まず、一意の制約とドメインの制約を使用しPositionて、テーブルに列を追加します。いずれにせよ、列が必要になる場合があります。一般に、サロゲート キーで並べ替えたり、並べ替え情報を完全に破棄したりするのではなく、自然な順序で行を明示的に並べ替える方が適切です。Answers(q_id, Position)Position > 0 AND Position <= 4Position

これにより、次のようにデータベースにクエリを実行するように設定されます。

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 またはアプリケーション層コードが必要になる場合があります。

于 2013-02-28T20:18:05.390 に答える