みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

SQL文の抽出がうまくいきません。ご指導お願いいたします。

写真を添付していない投稿も表示させたいのです。
今のSELECT文だと写真添付されているものだけ抽出されます。
tokou_table(略t)
┌───┬────┬────┐
|tku_id|cont_id |post_id |
├───┼────┼────┤
|001  | 5   |21   |
├───┼────┼────┤
|002  | 4   |22   |
└───┴────┴────┘
post_table(略p)
┌───┬────┬────┐
|pst_id|cont_id |atch_id |
├───┼────┼────┤
|21 | 5 |0    |
├───┼────┼────┤
|22 | 4 |1 |
└───┴────┴────┘
post_text_table(略pt)
┌───┬────┬────┐
|pst_id|pst_sub |pst_txt |
├───┼────┼────┤
|21 | 実験 |テキスト|
├───┼────┼────┤
|22 |サンプル|書込み |
└───┴────┴────┘
atch_table(略at)
┌───┬────┐
|pst_id|atch_id |
├───┼────┤
|21 | 51 |
└───┴────┘

atch_dat_table(略ad)
┌────┬────┐
|atch_id |pht_dat |
├────┼────┤
|51 |a.jpg |
└────┴────┘

$sql = "SELECT t.tku_id, t.cont_id, p.forum_id, p.pst_id, pt.pst_id, pt.pst_txt, ad.atch_id, at.pst_id, at.atch_id, ad.pht_dat
FROM " . TOKOU_TABLE . " AS t, " . POST_TABLE . " AS p, " . POST_TEXT_TABLE . " AS pt," . ATCH_TABLE . " AS at, " . ATCH_DAT_TABLE . " AS ad
WHERE t.cont_id = 4
AND t.cont_id = p.cont_id
AND p.pst_id = t.post_id
AND p.pst_id = pt.pst_id
AND pt.pst_id = at.pst_id
AND at.atch_id = ad.atch_id

投稿日時 - 2006-03-02 10:28:36

QNo.2001402

困ってます

質問者が選んだベストアンサー

#4回答者です。

対応するデータがなくても結果を得るには、OUTER JOINを使用する場合が多いですが、サポートバージョンが、マニュアルを見た範囲では「4.0.11以降」なのかも知れません。

既に「5.0」も正式リリースされていますが、バージョンアップは可能でしょうか?

■SQL記述例
略t→略p→~→略adの階層順に、子供に相手がいなくても、NULL値で結合する例です。
バージョン5.0で実機確認済みですが、あなたの希望通りかどうか分からないので確認してみてください。

SELECT t.tku_id, t.cont_id, p.forum_id, p.pst_id, pt.pst_id, pt.pst_txt,
ad.atch_id, at.pst_id, at.atch_id, ad.pht_dat
FROM TOKOU_TABLE AS t
LEFT OUTER JOIN POST_TABLE AS p
ON t.cont_id = p.cont_id AND p.pst_id = t.post_id
LEFT OUTER JOIN POST_TEXT_TABLE AS pt
ON p.pst_id = pt.pst_id
LEFT OUTER JOIN ATCH_TABLE AS at
ON pt.pst_id = at.pst_id
LEFT OUTER JOIN ATCH_DAT_TABLE AS ad
ON at.atch_id = ad.atch_id
WHERE t.cont_id = 4
;

参考URL:http://dev.mysql.com/doc/refman/4.1/ja/join.html

投稿日時 - 2006-03-02 15:01:12

お礼

的確なご指導ありがとうございます。

LEFT OUTER JOINでもできました。すばらしい、さすがですね。
本当に感謝いたします。
JOINでもWHEREが使用できるのは知らなかったです。
みなさまのご指摘によりテーブルを4つにしてみてLEFT JOINでもできました。
一応下記になりました。

$sql = "SELECT t.tku_id, t.cont_id, pt.pst_id, pt.pst_txt, ad.atch_id, at.pst_id, at.atch_id, ad.pht_dat
FROM " . TOKOU_TABLE . " AS t
LEFT JOIN " . POST_TEXT_TABLE . " pt ON pt.post_id = t.post_id
LEFT JOIN " . ATCH_TABLE . " at ON at.pst_id = pt.pst_id
LEFT JOIN " . ATCH_DAT_TABLE . " ad ON at.atch_id = ad.atch_id
WHERE t.cont_id = 4
ORDER BY t.con_id DESC ";

添付していない投稿の表示されない画像は透明なGIFで対応しました。
まだ改善の余地はありそうです。
ご指導ありがとうございました。

投稿日時 - 2006-03-02 15:17:38

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

5階層になっているようですが、対応するデータの有無により、対応付けの要否が分かりません。

MySQLの質問をする場合は、バージョンも書いてくださいね。
せっかくSQL例を提示しても、バージョンによる実行可否がありますから。

投稿日時 - 2006-03-02 11:38:41

補足

そうですよね。大変失礼しました。
MySQLは4.0.0-alphaです。
phpによる記述になります。
phpは4.2.3です。
ご指摘ありがとうございました。

投稿日時 - 2006-03-02 12:55:24

ANo.3

これはPHPで処理しているのでしょうか?
そもそもFROM節のつなぎ方に文法的な問題がありそうです。
このままではまともに動かないと思いますけど。

本題:
ファイルのアタッチがあるものとないものがあり
両方表示したいのですよね?
そういう場合はadテーブルでatch_id=0でNULLを作っておき
atテーブルでアタッチがないものを0指定すればよいのでは?
(0じゃなくても特徴的な番号999とかでもいいです)
後はうけとった側でNULLを例外処理すればすむので。

投稿日時 - 2006-03-02 11:17:21

補足

回答ありがとうございます。
大変参考になるご意見ありがとうございます。
ただ、atテーブルのレコードが増えていくという形になるので
なるべくならatテーブルのレコードは添付しているものだけの
レコードにしたいのです。
でも、できなければご指導いただいたようにするしかないのかな
と思っています。
JOIN を使って今やっていますが。。。難しいです。
JOINを使うやり方でいい構文がありましたらご指導ください。

投稿日時 - 2006-03-02 12:58:32

ANo.2

どのような仕様かはわかりませんが、テーブルを分けすぎだと思います。

それはさておき、whereで全てのテーブルがないと連結できないので対象からはずれてしまいます。
その場合は、あるかないかが分からないものに関しては
left joinで連結してみてください。
データがなくてもNULLが入るはずです。

投稿日時 - 2006-03-02 10:51:58

お礼

回答ありがとうございます。
テーブルは訳あって分けています。
ご指摘の通り、ひとつに出来れば簡単な話なんですが、すみません。

left joinでやってみます。わからなければ再度質問させてください。

投稿日時 - 2006-03-02 11:11:00

ANo.1

テーブルが細分化されていますがまとめたらだめなんでしょうか。
idの役割が不明なのでわかりませんが全部のテーブルを1つにまとめられそうな気がします。
目的があって分けてあるのでしたらすみません。

投稿日時 - 2006-03-02 10:51:31

お礼

回答ありがとうございます。
ご指摘の通り、テーブルをひとつにできれば簡単なんですけど。
サーバレスポンスと写真の添付の関係でこういう仕様になっています。
投稿に写真添付が何枚も投稿できるようにと。。。
そこがエーラーの原因なのですが、なんとかがんばって作ってみたいと思います。

投稿日時 - 2006-03-02 11:16:26

あなたにオススメの質問