1

ユーザーが別のユーザーにメッセージを送信できるようにするユーザー向けのメッセージングシステムを作成しました。

このために、2つのテーブルを作成しました。

  conversation(conversation_id,user_id1,user_id2)
  messages(message_id,conversation_id,sender_id,receiver_id,message,created_time)

ユーザーが初めて話している場合、conversation_idはuser_id1(チャットを開始する人)とuser_id2(user_id1がメッセージを送信する人)で作成されます

メッセージテーブルには、メッセージに関連するすべての情報が含まれます。

今私が欲しいのは、ログインしたユーザーが他のユーザー間のすべての会話リストをcreated_timeで並べ替え、conversation_idでグループ化して表示できるメッセージ要約ページを作成することです。

テーブルデータは次のとおりです。

conversation_id | user_id1 | user_id2
     1                100       103
     2                101       103
     3                103       102        


message_id| conversation_id| sender_id| receiver_id| message | created_time
   1             1            100       103           MSG A    2012-06-08 08:38:57
   2             1            103       100           MSG B    2012-06-08 08:39:40
   3             2            101       103           MSG C    2012-06-08 08:40:20
   4             3            102       103           MSG D    2012-06-08 08:41:10

そして、これが私が探しているものの出力です:ログインしたユーザーがID:103であるとしましょう

conversation_id| conversation_with | last_message | created_time
      3              102              MSG D         2012-06-08 08:41:10
      2              101              MSG C         2012-06-08 08:40:20
      1              100              MSG B         2012-06-08 08:39:40

したがって、この出力は、created_timeで並べ替え、conversation_idでグループ化し、conversation_withにユーザーID103が会話しているユーザーのIDを表示します。

誰かがMySQLクエリを提供できますか?この出力を取得する必要があります。

4

1 に答える 1

1

これは楽しいものでした。したがって、解決すべき3つの主要なことがあります。

  1. conversation_with2つの列の中で目的のユーザーが表示される場所に応じて、列を交互に切り替えます。
  2. greatest-n-per-group最新のものを見つけるためにmessage
  3. least-n-per-group最も早いメッセージを見つけるためにcreated_time

最初の問題は、2回クエリを実行し、user_id列を交互に並べ、結果を結合してから、結合された結果を。で並べ替えることで解決しましたcreated_time。ユニオンなしで1つのクエリでこれを解決できると思いますが、今のところは機能します。

2と3はもう少し複雑です。クエリを使用したSQLフィドルは次のとおりです。http://sqlfiddle.com/# !2/bf2b7 / 1

TL; DNR

select * from (
    select c.conversation_id, c.user_id2 as conversation_with, m1.message as last_message, m3.created_time 
    from conversation as c
      join messages as m1 on c.conversation_id = m1.conversation_id
      left outer join messages as m2 on (c.conversation_id = m2.conversation_id 
                                         and (m1.created_time < m2.created_time OR m1.created_time = m2.created_time AND m1.message_id < m2.message_id))
      join messages as m3 on c.conversation_id = m3.conversation_id
      left outer join messages as m4 on (c.conversation_id = m4.conversation_id
                                         and (m3.created_time > m4.created_time OR m3.created_time = m4.created_time AND m3.message_id > m4.message_id))
    where user_id1 = 103 and m2.message_id is null and m4.message_id is null
  union all
    select c.conversation_id, c.user_id1 as conversation_with, m1.message as last_message, m3.created_time 
    from conversation as c
      join messages as m1 on c.conversation_id = m1.conversation_id
      left outer join messages as m2 on (c.conversation_id = m2.conversation_id 
                                         and (m1.created_time < m2.created_time OR m1.created_time = m2.created_time AND m1.message_id < m2.message_id))
      join messages as m3 on c.conversation_id = m3.conversation_id
      left outer join messages as m4 on (c.conversation_id = m4.conversation_id
                                         and (m3.created_time > m4.created_time OR m3.created_time = m4.created_time AND m3.message_id > m4.message_id))
    where user_id2 = 103 and m2.message_id is null and m4.message_id is null
                                        ) as conversations
order by created_time desc
于 2012-06-09T05:40:01.400 に答える