【问题标题】:Displaying messsage in specific format in mysql php在mysql php中以特定格式显示消息
【发布时间】:2012-06-09 15:50:53
【问题描述】:

我为用户创建了一个消息传递系统,允许用户向另一个用户发送消息。

为此,我创建了两个表。

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

如果用户是第一次交谈,将使用 user_id1(发起聊天的人)和 user_id2(向 user_id1 发送消息的人)创建一个 conversation_id

Messages 表将包含与消息相关的所有信息。

现在我想要的是,创建一个消息摘要页面,登录用户可以在其中查看他在其他用户之间的所有对话列表,按 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 中显示用户的 id,与用户 ID 103 正在交谈的人。

谁能提供我需要得到这个输出的 MySQL 查询。

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    这很有趣。因此,您需要解决三个主要问题。

    1. 根据所需用户在两列中的显示位置交替使用 conversation_with 列。
    2. greatest-n-per-group 查找最新的message
    3. least-n-per-group查找最早的消息created_time

    我通过查询两次解决了第一个问题,交替user_id 列,合并结果,然后按created_time 对合并结果进行排序。我想我可以用一个查询而不用联合来解决这个问题,但它现在有效。

    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
    

    【讨论】:

    • 需要进行大量性能测试,但通常greatest/least-n-per-group 非常有效。您需要在 created_time 上添加和索引,如果您在消息和对话之间创建外键,这些也会被索引。
    • 我将 SQL fiddle 更新为包含一些主键、索引和外键的版本。
    • 你好!!我已经更新了我的表格并在这里扩展了我的问题。我相信你可以帮忙..stackoverflow.com/questions/10965529/…
    猜你喜欢
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多