- ベストアンサー
SQL文の重複の削除でうまくいきません。
昨日は回答いただきありがとうございました。 恐縮ですが、また質問させていただきます。 ひとつの投稿に対して2つの添付ファイルがある場合post_tableのtku_idが重複しているのですが、それに対してpost_idの小さい方を表示させたいのです。 post_tableのデータはpst_idで22と23がtku_idが同じで、22の方を表示させたいのです。 GROUP BY HAVING や自己リレーpost_table p2などやってみましたがダメでした。 どういうSQL文にするのがベストなんでしょうか? 未熟ものですが、ご指導いただけると助かります。 宜しくお願いいたします。 $sql = "SELECT t.tku_id, t.cont_id, p.pst_id, p.tku_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_TABLE . " p ON t.cont_id = p.cont_id LEFT JOIN " . POST_TEXT_TABLE . " pt ON p.pst_id = pt.pst_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 GROUP BY p.tku_id ORDER BY t.cont_id DESC "; tokou_table(略t) tku_id cont_id post_id 001 5 21 002 4 22 post_table(略p) pst_id cont_id atch_id tku_id 21 5 0 001 22 4 1 002 23 4 1 002 post_text_table(略pt) pst_id pst_sub pst_txt 21 実験 テキスト 22 サンプル 書込み atch_table(略at) pst_id atch_id 21 51 23 52 atch_dat_table(略ad) atch_id pht_dat 51 a.jpg 52 b.jpg MySQLは4.0.0-alph php4.2.3による記述です。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 SQL文のみですが、下記みたいになるかと思います。 --- SELECT q.*, pt.*, at.*, ad.* FROM ((( SELECT t.tku_id, t.cont_id, p.forum_id, Min(p.pst_id) AS pst_id_m FROM tokou_table t LEFT JOIN post_table p ON t.cont_id = p.cont_id GROUP BY t.tku_id, t.cont_id, p.forum_id HAVING (t.cont_id)="4" ) q LEFT JOIN post_text_table pt ON q.pst_id_m = pt.pst_id ) LEFT JOIN atch_table at ON pt.pst_id = at.pst_id ) left join atch_dat_table ad ON ad.atch_id = at.atch_id;
その他の回答 (4)
- o_chi_chi
- ベストアンサー率45% (131/287)
#1です。 SELECT t.tku_id, t.cont_id, p.forum_id, Min(p.pst_id) AS pst_id_m FROM tokou_table t LEFT JOIN post_table p ON t.cont_id = p.cont_id GROUP BY t.tku_id, t.cont_id, p.forum_id HAVING (t.cont_id)="4" の部分を別名でqとしています。 --- MySQLは昔使ったことがあるのですが、 あまり仕様を覚えていないので。。。。。
お礼
ご回答ありがとうございました。 まだ試行錯誤しながらやってみてます。 また機会がありましたら宜しくお願いします。
- yambejp
- ベストアンサー率51% (3827/7415)
#2の補足です。バージョン次第ですがMySQL使いとしては サブクエリーは使わないものとして・・・。 SELECT min(pst_id) as pst_id,cont_id,atch_id,tku_id from p group by tku_id; とするとtku_idをユニークなテーブルが表示されます。 このデータをテンポラリーに流し込んで、pの変わりに 使えば、うまくいくと思います。 CREATE TEMPORARY TABLE temp_p SELECT min(pst_id) as pst_id,cont_id,atch_id,tku_id from p group by tku_id; SELECT t.tku_id, t.cont_id, temp_p.pst_id,pt.pst_txt, ad.atch_id, at.pst_id, at.atch_id, ad.pht_dat FROM t LEFT JOIN temp_p ON t.cont_id = temp_p.cont_id LEFT JOIN pt ON temp_p.pst_id = pt.pst_id LEFT JOIN at ON at.pst_id = pt.pst_id LEFT JOIN ad ON at.atch_id = ad.atch_id WHERE t.cont_id = 4
お礼
ご回答ありがとうございました。 まだ試行錯誤しながらやってみてます。 また機会がありましたら宜しくお願いします。
補足
お忙しい中、ご回答ありがとうございます。 いろいろ作戦があるんですね。関心してしまいます。 o_chi_chiさんとyambejpさんどちらも検証しています。 Mysqlのエラーなのか構文が間違っているのか、エラーになるので 調べています。 必ずお返事いたしますので、しばらくお待ちください。 回答本当にありがとうございます。感謝です。
- yambejp
- ベストアンサー率51% (3827/7415)
添付されるファイルの上限値が少数できまっている たとえばどんなに多くても5個とか・・・ であれば、予めフィールドを5個つくっておくと 効率的です。添付データが1つしかなくても、 残りのフィールドには0とかNULLを入れておけばいいの ですから。(その辺は前回もお答えしましたので割愛) 上限値が決まっていないもしくは上限値があるが 数量が多い、たとえば100とか・・・の場合は、 結果は行で別れている方が後処理しやすいでしょうね。 そもそもが戻ってきた結果をどう表現したいのかも 提示されていないので、なんとも答えようがありません。 SQLは所詮データの塊でしかないので、全ては結果を 表示したり保存したりする仕様次第でしょう。
補足
回答ありがとうございます。 ご指摘の通りフィールドをあらかじめ作る方が楽なんですけど。。。 SQLもそのほうが簡単ですよね。 でも今回はこれでいきたいと思います。 結果を説明させていただくと、投稿したデータに写真が掲載されるという仕組みです。 投稿する写真は何枚でも掲載できるようにしています。 プログラムで表示させたいのは一覧で表示する際に写真をひとつだけ表示したいのです。 投稿に写真を追加して2枚になっても表示は一番最初に投稿した写真が表示したいのです。 現状のSQLだと最後に投稿したものが表示されるようになっています。 投稿するとt、p、ptにそれぞれレコードが追加されます。 写真を添付するとat、adにレコードが追加されます。
- o_chi_chi
- ベストアンサー率45% (131/287)
SQL文を2つに分けたらどうですか。 1.tとpを連結しtku_idでグループ化しMIN(post_id)で 最小値と必要項目を取得。 2.そのSQLと残りのテーブルを連結させて残りの必要な 項目を取得。
お礼
回答ありがとうございます。 2つに分けるやり方でやってみましたが、構文が違うのかうまく いきませんでした。 もうすこしがんばってみたいと思いますが、具体的にどういうSQL文に なるのか教えていただけるとたすかります。 お手数おかけして申し訳ないです。よろしくお願いします。
補足
SQL文ありがとうございます。 いろいろやってみてますが、エラーになってしまいます。 Verの問題かもしれないので、自力でやっています。 q となっているのは p の間違いではないですよね? 丁寧にご回答いただきありがとうございます。