- ベストアンサー
データベースから読み込んで表示させる方法について
PHP、MySQL共に超初心者です。 説明も下手で申し訳ないのですが、どうぞご教授お願いいたします。 WEBページから小説をデータベースに登録させる管理画面をPHPで作成しております。 登録はうまくいったのですが、登録内容を一覧表示させるページで、思ったように表示させることが出来なくて困ってしまいました。 テーブルの主な内容は以下の通りです。 ■genre(ジャンル名テーブル) └【id】…数字 【genre_name】…小説のジャンル名 ■novel●●(小説を入れるテーブル。●●の部分はgenreテーブルの【id】と同じ) └【genre】…genreテーブルの【id】と同じにしてジャンル分け。 【title】…小説タイトル 【writing_date】…執筆日 【release】…0は非公開、1は公開。 やりたいことは、 【release】が1(公開)となっている【title】(小説タイトル)を、【writing_date】(執筆日)の新しい順に全て表示させ、それを【genre】ごとにまとめたテーブルに表示させる事。 (【release】が0しかないジャンルは表示させない) です。 現在、公開設定となっていない小説しかないジャンルまでもが表示されてしまっています。 (もちろん内容がないので、ジャンル名と項目名だけが不恰好に表示されてしまいます。) 結合など色々検索して試してみたのですが、解決できずにいます。 どのような方法があるか 本当に説明下手で大変申し訳ないのですが、ご助力宜しくお願いいたします。 初心者ゆえ、どこまで説明すれば良いかもわかっておりませんので、説明不足な部分は補足させていただきます。 どうぞ宜しくお願いいたします。 ■環境 MYSQL:4.0.24 PHP:5.2.6 ■プログラム <?php $genre_sql = "select * from genre"; $genre_que = mysql_query($genre_sql); while ($genre_row = mysql_fetch_array($genre_que)) { $genre_id = $genre_row['id']; $genre_id = sprintf("%02d", $genre_id); $genre_name = $genre_row['genre_name']; $novel_sql = "select * from novel$id order by writing_date desc limit 1"; $novel_que = mysql_query($novel_sql); while ($novel_row = mysql_fetch_array($novel_que)) { $novel_id = $novel_row['id']; $novel_genre = $novel_row['genre']; echo "▼".$genre_name. "<br> <table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tr> <td class=\"tdTitleEdi\" width=\"90%\">タイトル</td> <td class=\"tdTitleEdi\" width=\"10%\">更新日</td> </tr>"; $title_sql = "select * from title$genre_id"; $title_que = mysql_query($title_sql); while ($title_row = mysql_fetch_array($title_que)) { $title_id = $title_row['id']; $title_name = $title_row['title_name']; $novel_sql = "select * from novel$genre_id where genre=$genre_id and title=$title_id"; $novel_que = mysql_query($novel_sql); while ($novel_row = mysql_fetch_array($novel_que)) { $novel_id = $novel_row['id']; $novel_genre = $novel_row['genre']; $novel_title = $novel_row['title']; $novel_writing_date = $novel_row['writing_date']; $novel_release = $novel_row['release']; echo "<tr>"; echo "<td class=\"tdEdiTi\">"; $novel_sql = "select * from novel$genre_id where genre=$genre_id and title=$title_id"; $novel_que = mysql_query($novel_sql); while ($novel_row = mysql_fetch_array($novel_que)) { echo $title_name; echo " </td>"; } } } echo "<td class=\"tdEdiLi\">"; $novel_sql = "select * from novel$genre_id where genre=$genre_id and title=$title_id order by writing_date desc limit 1"; $novel_que = mysql_query($novel_sql); while ($novel_row = mysql_fetch_array($novel_que)) { $year = mb_substr($novel_writing_date,0,4); $month = mb_substr($novel_writing_date,5,2); $day = mb_substr($novel_writing_date,8,2); echo $year. "." .abs($month). "." .abs($day); } echo " </td>"; echo "</tr>"; } } echo "</table>\n"; } } ?>
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
私も、No.1のご回答にあるように、novelテーブルの設計の見直しをおすすめします。 novelテーブルは●●などで分けずに、1つで十分です。 私が作るとしたら、例えば、 ■novel └【id】…小説のid。内容を更新する時などに使います。 【genre_id】…genreテーブルの【id】と同じにしてジャンル分け。 【title】…小説タイトル 【writing_date】…執筆日 【release】…0は非公開、1は公開。 のようにするのですが、そうすると、お調べになった結合などが容易にできるようになります。 今は、テーブルが●●で分かれているために、結合ができない(やってできない事はないけど説明は割愛)のです。 そうすると、SQLの実行は1回だけで済ませる事もできるようになります。 プログラム全体を変更するようになるので、これも今は割愛します。 で、今のままで何とかするだけしてみる作戦。 プログラムの3段落目のSQL文に、条件を追加してみましょう。 ※掲載されたプログラムを、環境を作って試験実行してみたのですが微妙に修正しなければならないところがありましたので、試験実行は中止して、もしかしたらこれだけでいいのかな、と思ったので。 $novel_sql = "select * from novel$id order by writing_date desc limit 1"; ↓ $novel_sql = "select * from novel$genre_id where release=1 order by writing_date desc limit 1"; これだけです。 ※ novel$id は novel$genre_id の間違いではないかと思う。 この時点で実行されるSQLで、そのジャンルにおける公開設定となっている小説がなければ、その内側のループをしないので、ジャンル名も表示されなくなると思います。 そうすると、次のジャンルの処理になるので、いいのではないでしょうか。 試験実行していないのでわかりませんが、もしだめならまた少しずつ調整するとして、やってみてください。
その他の回答 (1)
- UmJammer
- ベストアンサー率58% (115/196)
まずテーブル設計を見直した方がよいかと思います。 novel●●の「●●」の部分が必要だとは思えないのですが、何か特別な理由があるのでしょうか。ジャンルテーブルのIDはgenreというフィールドとして持っているわけですよね。 結果、煩雑にSQLを発行する羽目になっているのだと思います。 可能なら検討してみてください。
お礼
●●と分けている事に特に理由はなく、ただ単にプログラムしやすいんじゃないかなと勘違いして分けていただけです( ;^^)ヘ.. なので、おっしゃる通り、テーブル設計を見直して再度チャレンジしてみます! 本当にありがとうございました!!
お礼
非常に解りやすい解説、本当にありがとうございました! ご指摘通り、 $novel_sql = "select * from novel$genre_id where release=1 order by writing_date desc limit 1"; ↑こちらに変更したらうまく登録されたジャンルのみのテーブルを表示させる事ができました! ●●で分けていないテーブルは最初に作っていたのですが、分けたほうがプログラムしやすいかなと勘違いして分けてしまいました。 分けてない方法で十分との事でしたので、今度はそちらでチャレンジしてみます。 本当にありがとうございました!!