1

ユーザー通信用のメッセージシステムをコーディングしています。受信トレイでは、受信したメッセージをユーザーに表示したくありません。会話を見せたいだけです。したがって、例として、1 人のユーザーが複数のメッセージを送受信する場合、受信トレイにはユーザーとの会話 (作成または受信された最新のメッセージを含む) のみが存在し、ユーザーが会話をクリックすると、彼/彼女は過去のメッセージをすべて見ることができます。

「メッセージ」のテーブル構造 (簡略化) は次のとおりです。

message_id
user_id_sender
user_id_recipient
message

ここでの問題は、各行が 1 つのメッセージであるデータベースにメッセージが保存されるため、特定の方法でこれらのメッセージをグループ化する必要があることです。

私が思いついた選択ステートメントは次のとおりです。

SELECT * FROM messages
WHERE user_id_sender = 1 OR user_id_recipient = 1
GROUP BY user_id_sender

しかし、ユーザー「1」が書いたものと、彼が受け取ったものがあるため、明らかに2つのメッセージを受け取ります..

これを解決する方法を知っている人はいますか?

4

4 に答える 4

2

私は数ヶ月前にこの問題を解決しました。畑もあると思いますdate。このクエリは、最後のメッセージの日付と最後のメッセージを含む適切に構造化された結果を提供します。

$qry = 'SELECT 
CONCAT(GREATEST(user_id_sender,user_id_recipient)," ",LEAST(user_id_sender,user_id_recipient)) AS thread, 
MAX(CONCAT(date,"|",message)) as date_message, 
MAX(date) AS last_message, 
messages.* 
     FROM messages
     WHERE user_id_sender= ? || user_id_recipient=? GROUP BY thread ORDER BY last_message DESC';

$rows = $db->fetchAll($qry, Array($current_user_id,$current_user_id));
于 2012-11-03T21:17:50.617 に答える
2

message_id が昇順であると仮定します (つまり、ID が大きいほど後のメッセージになります)。@user_idは、見ている受信トレイの単なるプレースホルダーですuser_idother_recipient_id簡潔に取得するためにアンドレアのトリックを使用しました。

Select 
  mm.other_recipient_id,
  m.*
From (
  Select
    user_id_sender + user_id_recipient - @user_id as other_recipient_id,
    Max(message_id) as message_id
  From
    messages
  Where
    user_id_sender = @user_id Or
    user_id_recipient = @user_id
  Group By
    user_id_sender + user_id_recipient - @user_id
  ) mm
    Inner Join
  messages m
    On
  mm.message_id = m.message_id

フィドルの例http://sqlfiddle.com/#!2/05d191/3/0

于 2012-11-03T20:40:46.673 に答える
0

message_idメッセージ( )が一意である限り、メッセージは1つだけ取得されます。もちろん、より長い通信が行われている場合は、複数のメッセージが表示されます。

group by注意:これは列の集計にのみ使用されるため、ここでは必要ありません。例:

SELECT user_id_sender, sum(*) FROM messages
GROUP BY user_id_sender;

ここで、各ユーザーが送信したメッセージの合計を取得します。

したがって、2人のユーザー間の通信を確認したい場合は、次のようにします。

SELECT * FROM messages
WHERE user_id_sender = 1 OR user_id_recipient = 1;

message_timeたとえば、タイムスタンプも保存する場合、または表示されるメッセージの数を制限する場合は、これをさらに制限できます。

select * from ... limit 10;
于 2012-11-03T20:36:25.163 に答える
0

特定の _ ID _ を持つユーザーの会話を見たいと仮定すると、次のクエリが役立ちます。

SELECT (user_id_sender + user_id_recipient) - _ID_ AS correspondent, COUNT(*) AS total
FROM messages
WHERE user_id_sender = _ID_ OR user_id_recipient = _ID_
GROUP BY (user_id_sender + user_id_recipient)

結果のクエリは、会話の他のユーザーの ID (「対応者」) と 2 人のユーザー間のメッセージの数 (「合計」) を返します。

よろしく

于 2012-11-03T20:52:23.617 に答える