Creating a messages list in SQL

自古美人都是妖i 提交于 2020-01-06 06:49:33

问题


I'm trying to create a messages list, like Facebook.

  1. Showing only last the message from a users conversation (history)
  2. when I send show mine , when I get answer show answered messages (1 row)

database data :

SQL query

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

I try to receive all messages which I send (my id = 3) and all those sent to me and group by username

SQL result:

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
        )

)

As you can see GROUP BY username do not work. It shows 3->7 and 7->3 but 7->3 was an answer and last message. I do not know why group does not work. Maybe you can help me with more easier way to solve this problem?

So, the SQL must have "sender_id = 3" , "receiver_id = 3" and from my table data result must be

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

回答1:


I think your query is producing the “right” results, as if you'd like to see the last message in some of the conversations, you should really group by the conversation_id. I don't see this field you in schema though.

If you do WHERE sender_id = 3 GROUP BY receiver_id, then it is correct, that query returns you messages 1 and 7, 'cos those messages had been sent to different people, thus in your design they're different conversations.

If you want to see only the very last message sent by you in general, just remove GROUP BY in the second part of your UNION. Otherwise, consider re-designing your schema.


EDIT:

Try this query:

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)
    );

Some notes:

  1. UNION is not needed anymore;
  2. This approach will treat all e-mails between 2 parties as a single conversation, which is not always true. You might want to re-design this approach;
  3. It is a bad style to use reserved words (like date) for columns' names or aliases, try to avoid this. Or use backticks if you do use them.


来源:https://stackoverflow.com/questions/11921204/creating-a-messages-list-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!