0

Facebookのようなメッセージリストを作成しようとしています。

  1. ユーザーの会話からの最後のメッセージのみを表示(履歴)
  2. show mineを送信するとき、回答を受け取るときshow Answeredメッセージ(1行)

データベースデータ

ここに画像の説明を入力してください

SQLクエリ

SELECT m.message_id, u.username, m.subject, m.message
     , m.status, UNIX_TIMESTAMP(m.date) as date
  FROM users u
  LEFT JOIN messages m ON m.sender_id = u.id
 WHERE m.message_id in (SELECT max(msg.message_id) 
                          FROM messages msg 
                         WHERE msg.receiver_id = 3 
                         GROUP BY sender_id)
 UNION
SELECT m.message_id, u.username, m.subject, m.message
     , m.status, UNIX_TIMESTAMP(m.date) as date
  FROM users u
  LEFT JOIN messages m ON m.receiver_id = u.id
 WHERE m.message_id in (SELECT max(msg.message_id)  
                          FROM messages msg 
                         WHERE msg.sender_id = 3 
                         GROUP BY receiver_id)
 GROUP BY u.username
 ORDER BY date DESC

私が送信するすべてのメッセージ(私のID = 3)と、私に送信されたすべてのメッセージを受信しようとし、ユーザー名でグループ化します

SQLの結果:

Array
(
    [0] => Array
        (
            [message_id] => 10
            [username] => 8888
            [subject] => без темы
            [message] => 555
            [status] => 0
            [date] => 11 August 2012, 2:22
            [user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
        )

    [1] => Array
        (
            [message_id] => 7
            [username] => 8888
            [subject] => hi
            [message] => 333
            [status] => 0
            [date] => 11 August 2012, 2:15
            [user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
        )

    [2] => Array
        (
            [message_id] => 4
            [username] => 6666
            [subject] => Тема
            [message] => 2
            [status] => 0
            [date] => 11 August 2012, 2:02
            [user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
        )

    [3] => Array
        (
            [message_id] => 1
            [username] => fffffffff
            [subject] => privet
            [message] => tttt
            [status] => 0
            [date] => 11 August 2012, 1:38
            [user_image] => http://127.0.0.1/auth_system_1/upload_images/65_empty.jpg
        )

)

ご覧のとおり、GROUP BYユーザー名は機能しません。3->7と7->3が表示されますが、7->3が回答で最後のメッセージでした。グループが機能しない理由がわかりません。たぶんあなたはこの問題を解決するためのより簡単な方法で私を助けることができますか?

したがって、SQLには「sender_id = 3」、「receiver_id = 3」が必要であり、テーブルデータからの結果は次のようになります。

  • message_id-> 1
  • message_id-> 4
  • message_id-> 10
4

1 に答える 1

1

あなたのクエリは「正しい」結果を生成していると思います.会話のいくつかで最後のメッセージを見たい場合は、conversation_id. ただし、このフィールドはスキーマには表示されません。

もしそうならWHERE sender_id = 3 GROUP BY receiver_id、それは正しいです。そのクエリはメッセージ 1 と 7 を返します。これらのメッセージは別の人に送信されたので、設計上は別の会話になります。

一般的に、あなたが送信した最後のメッセージだけを見たい場合GROUP BYは、UNION. それ以外の場合は、スキーマの再設計を検討してください。


編集:

このクエリを試してください:

SELECT m.message_id, u.username, m.subject, m.message,
       m.status, UNIX_TIMESTAMP(m.date) as `date`
  FROM users u
  LEFT JOIN messages m ON m.sender_id = u.id
 WHERE m.message_id IN (
    SELECT max(message_id) 
      FROM messages
     WHERE receiver_id = 3 OR sender_id = 3
     GROUP BY least(sender_id,receiver_id), 
              greatest(sender_id,receiver_id)
    );

いくつかのメモ:

  1. UNIONもう必要ありません。
  2. このアプローチでは、2 者間のすべての電子メールが 1 つの会話として扱われますが、これは常に正しいとは限りません。このアプローチを再設計することをお勧めします。
  3. date列の名前やエイリアスに予約語 ( など) を使用するのは不適切なスタイルです。これは避けてください。または、使用する場合はバッククォートを使用してください。
于 2012-08-12T10:17:45.383 に答える