質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

753閲覧

EXISTS句でのソートが上手くいかずに困ってます。ご教示ください。

chapp

総合スコア233

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/05/18 10:52

お世話になります。表題の通りですが、EXISTS句でのソートが上手くいかずに困ってます。

会員同士でメッセージのやり取りが行われており、やり取りしている相手の一覧が添付の画像のように並んでいます。
(この一覧をクリックすることで、それぞれのメッセージにアクセスできる仕組み)

イメージ説明

今回ご教示願いたいのは、この一覧の順序で、送信時間が新しいもの順に並べたいのですが、現状は会員のno(auto_increment値)が新しいもの順になっている状況です。

■会員のテーブルはこちら(余計なカラムは削除しています)

CREATE TABLE `member` ( `member_no` int(11) NOT NULL, `member_id` varchar(255) NOT NULL, `member_mail` varchar(255) NOT NULL, `member_img` varchar(255) NOT NULL COMMENT 'ファイル名' ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

■メッセージのテーブルはこちら。

CREATE TABLE `message` ( `message_no` int(11) NOT NULL, `message_to_member_no` int(11) NOT NULL, `message_from_member_no` int(11) NOT NULL, `message_exp` text NOT NULL, `message_file` varchar(255) NOT NULL COMMENT 'ファイルを,区切りで', `message_flag` enum('','hold') NOT NULL, `message_date` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /* message_from_member_noが送信者の会員No message_to_member_noが受信者となる会員No message_flag に"hold"という値がある場合は未読として処理 message_dateは送信時間 */

■そして肝心のリスト表示させているSQLは以下の通り。

/* 変数 $member_no は、自身の member_no。*/ $query = "SELECT member.member_no, member.member_id, member.member_img FROM member WHERE EXISTS(SELECT 0 FROM message WHERE (message_to_member_no = member.member_no AND message_from_member_no = $member_no) OR (message_from_member_no = member.member_no AND message_to_member_no = $member_no) ORDER BY message_date DESC LIMIT 1 ) ORDER BY member.member_no DESC"; $result = $mysqli->query($query); $page_cnt = $result->num_rows; if($page_cnt > 0){ while ($row = $result->fetch_assoc()) { if($row["member_img"] != ""){ $img_path = "/img_member/".$row["member_img"]; } else{ $img_path = "/images/no-image.jpg"; } $from_member_no = $row["member_no"]; $query2 = "SELECT message_to_member_no, message_from_member_no, message_flag FROM message WHERE message_to_member_no = '$member_no' AND message_from_member_no = '$from_member_no' AND message_flag = 'hold' ORDER BY message_no DESC"; $result2 = $mysqli->query($query2); $page_cnt2 = $result2->num_rows; if($page_cnt2 > 0){ $page_cnt2_view = "<span class=\"circle\">".$page_cnt2."</span>"; } else{ $page_cnt2_view = ""; } $side_area_member_list .= "<div class=\"MypageMessageList clearfix\"><div class=\"float-left\" style=\"width:40%;\"><img src=\"".$img_path."\" align=\"absmiddle\" class=\"image-round1\"></div><div style=\"float:left; width:60%;\"><a href=\"/Mypage/Message/?UserNo=".$row["member_no"]."\">".$row["member_id"]."</a> ".$page_cnt2_view."</div></div>"; } } /* 未読の値をバッジ表示すべく、お恥ずかしながら1つのSELECT文で処理できずに、回しながら都度SELECT文を置いてます。*/

お忙しいなか恐縮ですが、アドバイスのほど頂戴できれば幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ku__ra__ge

2021/05/18 11:26

EXISTS句でのソートが上手くいかないという質問の意図がわかりません。 EXISTS条件はレコードの抽出条件であるため、それに使って結果の並び方を意図したものにすることはできないと思いますが……。
chapp

2021/05/18 11:37

ご指摘ありがとうございます。質問が悪かったのかもしれませんが、記載したEXISTS句を使っているSELECT文において、うまくソートを変えることが出来ずにいる次第です。 質問文にあるSQLで、 ORDER BY member.member_no となっているものの、色々と変えているのですが、状況は変わりなく質問した次第です。
guest

回答1

0

ベストアンサー

  • $member_noがメッセージをやりとりした相手の一覧を表示したい
  • 相手ごとに最新のやり取り日時を算出し、その最新のやり取り日時の新しい順にソートしたい

↑ やりたいことはこれであっていますか? であればEXISTSではなくJOINをうまく使ったほうがよいかと思います。

SQL

1SELECT 2 member.member_no, 3 member.member_id, 4 member.member_img, 5 MAX(message.message_date) AS max_message_date 6FROM member 7JOIN message 8 ON (message.message_from_member_no = $member_no AND message.message_to_member_no = member.member_no) 9 OR (message.message_from_member_no = member.member_no AND message.message_to_member_no = $member_no) 10GROUP BY member.member_no, member.member_id, member.member_img 11ORDER BY max_message_date DESC

投稿2021/05/18 11:44

neko_the_shadow

総合スコア2349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chapp

2021/05/18 11:53

neko_the_shadowさま ありがとうございます。ご教示いただいたソースで実現できました。 EXISTSが前提にあったので、JOINという発想に至りませんでした。まだまだ勉強不足ですね。 ご親切な回答、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問