简体   繁体   中英

Creating a messages list in SQL

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM