Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL, finding most recent entry in conversation between two people

Tags:

sql

mysql

I have a table, Messages, which is set out as follows:

enter image description here

This table stores all messages sent between people, however it needs to be like FaceBook's message system.

To do this my query would need to be something like:

SELECT * FROM Messages WHERE To_User = x OR From_User = x ORDER BY Time DESC

This would fetch me every message 'x' either sent or received in order of time, newest ones appearing first.

However Facebook's system keeps it sort of like a forum, so I only want one message where person y is involved in any given query result. So I don't want this to happen:

To_User: 6 From_User: 7 Status: I agree with your message Time: 12345

To_User: 7 To_User: 6 Status: Do you agree with my message? Time: 12344

Say I was displaying the messages page for user 6, both messages would show up with my current system. Instead, only the top one should be selected, because I only want to display the most recent message between user 6 and 7, rather than every one.

Naturally this would usually just ask for a LIMIT statement but I need to be able to get a lot of messages, but the only rule is that:

1- It needs to be either FROM or TO user X 2- No two messages must be selected which are FROM or TO user Y 3- The messages selected must be the NEWEST in the conversation between user X and Y

This is really hard to describe but I hope I've described it in enough detail for a solution.

I've considered doing GROUP BY but I couldn't get it to take into account that it needed to find one that was either FROM or TO me rather than just only to or only from.

If the question isn't described in enough detail, please tell me before down-voting and I'll do my best to make it a bit more detailed, but I can't think of words to describe what needs to be displayed clearly enough.

Edit:

Here's a big example of the desired feature:

Say I sent a message to John Doe, and went on my messages page straight after, at the very top it'll say

"To John Doe" "The message I sent"

However if John Doe replies, that entry will not display on the page anymore, it'll be replaced by the newest entry in the conversation between me and John Doe, so while the actual entry is still in the database, it isn't shown anymore:

"From John Doe" "Your message is interesting"

But if I sent one to Jane Doe afterwards, it'd push me and John Doe's conversation so it looks like this:

"To Jane Doe" "Hello there"

"From John Doe" "Your message is interesting"

Now with the first query I stated in this post, the result would be:

"To Jane Doe" "Hello there"

"From John Doe" "Your message is interesting"

"To John Doe" "The Message I sent"

However I don't want to display more than one which is between me and John Doe, but since I'm looking at two different columns in the table (From and two) to dictate whether both I and John Doe are related, I don't think a regular GROUP BY statement would work.

Now, if in addition, Bob Joe sent me a message, it might look like:

"From Bob Joe" "Hello"

"To Jane Doe" "Hello there"

"From John Doe" "Your message is interesting"

like image 796
Ashley Davies Avatar asked Dec 28 '25 20:12

Ashley Davies


1 Answers

You can self-join the table and use an outer join, so that any "earlier" messages will "filter out" any "non-earlier" messages.

SELECT * FROM Messages main LEFT JOIN Messages earlier
    ON earlier.time < main.time AND 
        (
            earlier.To_User = main.To_User AND earlier.From_User = main.From_User OR  
            earlier.To_User = main.From_User AND earlier.From_User = main.To_User
        )
WHERE (main.To_User = x OR main.From_User = x) AND earlier.id IS NULL
ORDER BY main.Time DESC
like image 164
Jirka Hanika Avatar answered Dec 31 '25 11:12

Jirka Hanika