以前に、PHP&MySQLでクイズアプリを作成したのですが、中でもテーブルの「内部結合」でかなり苦労しました。
この記事では、その時の経験をもとにして、PHPで開発する際にテーブルを内部結合してデータを取得する具体的な方法について説明したいと思います。
こちらが完成品です。
ですね。
「内部結合」で検索してみると、理論的な説明記事はたくさんありますよね。
しかし、いざ記事をもとに作ろうとしても、前提条件が少し異なっていたり、うまく動作しなかったりと、苦労しました。
僕は複数の記事を読み漁ってなんとか実装しましたが、丸一日ほどかかってしまいました。。
このような経験から、ポイントを絞った上でのシンプルな解説であれば需要があるかなと思い、僕が書いたコードをシェアしたいと思います。
具体的には、次のような場合に的を絞って記事を書いています。
とはいえ、予備知識がないと難しいと思いますので、一応SQLの基礎を勉強したことがある方を想定しています。
テーブルを内部結合するのですが、イメージしやすくするために、フロントエンドの実装からお話しします。
上記の画面では、主に次の3つのテーブルからデータを取得&更新しています。
それぞれのテーブルの詳細です。
ちなみに、、
問題を解き終わったときに、以下の3つの情報をまとめた表を表示したい。
しかし、上記の3つの情報を持つテーブルは存在しません。
したがって、複数のテーブルから情報を集める必要があります。
具体的には、テーブルを結合して1つの大きな仮想テーブルを作成し、そのテーブルから情報を取得します。
イメージは湧いてきましたか?
より具体性を持たせるために、実際のデータを使って説明します。
この3つのテーブルを結合して、次のような仮想テーブルを作ります。
answerテーブルとquestionsテーブルの共通項。
answerテーブルとoptionsテーブルの共通項。
この2つの共通項を通じて、3つのテーブルを結合できそうです。
テーブルを内部結合するためのコードを書いていきましょう!
<?php
$dbh = new PDO('mysql:host=ホスト名;dbname=データベース名, ‘ユーザー名’, ‘パスワード’);
共通項目を利用して3つのテーブルを結合します。
ここが一番大変でした。。
$sql = "SELECT
options.option_details AS answer,
options.question_id AS question_id,
options.option_name AS option_name,
questions.question_deitails AS question,
questions.quiz_id AS quiz_id
FROM answer
INNER JOIN questions
ON answer.question_id = questions.question_id
INNER JOIN options
ON answer.answer_id = options.option_id
WHERE quiz_id ='" . $quiz_id . "'";
$stmt = ($dbh->prepare($sql));
$stmt->execute();
これで結合テーブルが出来上がりました。
実際には存在しないテーブルですので、一時的な仮想テーブルを作成しているというイメージですね。
次に配列を生成し、while文を使い、結合テーブルのデータを格納します。
$answers = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$answers[]=array(
'answer' =>$row['answer'],
'question' =>$row['question'],
'question_id'=>$row['question_id'],
'option_name'=>$row['option_name']
);
}?>
(*すみません、上記の$quiz_id=クイズIDは別途取得済みとさせてください。)
あとはforeachを使ってデータを表示すればOKですね。
<table class="quiz-table">
<tr>
<th>#</th>
<th>問題</th>
<th>答え</th>
<th>選択肢</th>
</tr>
<?php $c=1; foreach ($answers as $value): ?>
<tr>
<td>
<?php echo $c++ ?>
</td>
<td>
<?php echo $value['question'] ?>
</td>
<td>
<?php echo $value['answer'] ?>
</td>
<td>
<?php echo $value['option_name'] ?>
</td>
</tr>
<?php endforeach ?>
</table>
これで、記事の最初に見た結果画面が完成します😉