MySQL Selectステートメント-メッセージ用
質問
現在、プライベートメッセージングフォーラム用に次の表を用意しています:
代替テキストhttp://img159.imageshack.us/img159/45/pmdata .jpg
代替テキストhttp://img504.yfrog.com/img504/3968/pminfo .jpg
私がやろうとしているのは、「受信ボックス」を出力することです。送信者が誰であっても、一番上にスレッドごとに最新のスレッドを表示します(つまり、受信トレイに同じスレッドが2回表示されることはありません)。
私が今持っているものは、2つのユーザー間の単純なメッセージでうまく機能します。ただし、3人目のユーザーが同じスレッドに返信すると、正しく表示されません。私の現在のクエリはこれです:
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
INNER JOIN (SELECT thread_id, sender_id, MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id, sender_id) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent AND pm_data.sender_id = deriv1.sender_id
WHERE pm_info.receiver_id = '$usrID'
ORDER BY deriv1.thread_max_date_sent DESC
$ usrID = 68(したがって、receiver_id = 68)と仮定すると、次のように出力されます:
From: Kyle (pm_data.id = 18) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 12) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 8) RE: Test Number 2 (thread_id= 16256)
2つの異なる送信者があるため、thread_id(13587)が2回表示されることに注意してください。
送信者が誰であっても、最新のthread_idをちょうど表示するにはどうすればよいですか?
どうもありがとう!!
解決
実際には、元の質問のクエリは、各スレッドの実際の最新のレコードを取得するために非常に小さな変更のみを必要とするようです。
- sender_idをサブクエリのGROUP BYフィールドにドロップします
- ON句に pm_data.sender_id = deriv1.sender_id をドロップします
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent FROM pm_info INNER JOIN pm_data ON pm_info.message_id = pm_data.id INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID INNER JOIN (SELECT thread_id, /*sender_id,*/ MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id /*, sender_id*/) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent /*AND pm_data.sender_id = deriv1.sender_id*/ WHERE pm_info.receiver_id = '$usrID' ORDER BY deriv1.thread_max_date_sent DESC
補足:可能であれば、max(date_sent)の代わりにそのサブクエリでmax messageIDを探します
他のヒント
試用
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid
FROM pm_data, pm_info, tblUsers as sender
WHERE pm_info.message_id = pm_data.id
AND pm_data.sender_id = sender.usrID
AND pm_info.receiver_id = '$usrID'
GROUP BY thread_id
ORDER BY date_sent DESC
LIMIT 0,1
試用
SELECT pm_info.is_read, group_concat(DISTINCT sender.usrFirst) as sender_name,
pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid,
MAX(date_sent) AS thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
WHERE pm_info.receiver_id = '$usrID'
GROUP BY pm_data.thread_id
ORDER BY thread_max_date_sent DESC;
あなたのニーズに合わない場合は、group_concatの部分に自由に同意してください。 任意に選択するのではなく、関連するすべての送信者をリストするだけです。
データベースを2つのテーブルに分割して、正規化を改善することをお勧めします:" thread"および「メッセージ」。スレッドタイトルなど、すべてのメッセージに共通するスレッド情報があります。同じ値を繰り返すことで、メッセージテーブルのスペースを無駄にしています。
「最後の投稿時間」を設定できます新しい投稿ごとに更新されるスレッドテーブル。それは、スレッドテーブルから選択し、最後の投稿で並べ替えるだけの簡単な問題です。それも非常に高速になります。