I have a private messages table on my site and for a while now I have had an inbox and sentbox separate. I want to combine the inbox/sentbox only showing the latest message either to or from a specific user.
TLDR: I want to show the latest message grouped by sent to or from each user.
Example of table
| id | fromuser | fromid | touser | toid | message | timestamp |
--------------------------------------------------------------------------------
| 1 | user1 | 1 | user2 | 2 | Hello.. | 2015-01-01 00:00:00 |
| 2 | user1 | 1 | user3 | 3 | okay... | 2015-01-02 00:00:00 |
| 3 | user3 | 3 | user1 | 1 | not.... | 2015-01-03 00:00:00 |
| 4 | user2 | 2 | user3 | 3 | New.... | 2015-01-04 00:00:00 |
| 5 | user2 | 2 | user1 | 1 | With..... | 2015-01-05 00:00:00 |
--------------------------------------------------------------------------------
Result i'm looking for when in user 1
| id | fromuser | fromid | touser | toid | message | timestamp |
--------------------------------------------------------------------------------
| 3 | user3 | 3 | user1 | 1 | not.... | 2015-01-03 00:00:00 |
| 5 | user2 | 2 | user1 | 1 | With..... | 2015-01-05 00:00:00 |
--------------------------------------------------------------------------------
Using the code below I can get it to show one message to or from each user but it shows the oldest message not the newest.
mysql_query("SELECT m1.*, users.id AS userid, users.username
FROM pm AS m1, pm AS m2, users
WHERE ((m1.fromuser='".$_SESSION['userName']."' AND users.id=m1.toid)
OR (m1.touser='".$_SESSION['userName']."' AND users.id=m1.fromid))
AND m2.id=m1.id ORDER BY timestamp DESC");
Try this out:
select *
from messages m
where not exists (
select 1
from messages mm
where (mm.fromuser = m.fromuser or mm.fromuser = m.touser) AND (mm.touser = m.touser or mm.touser = m.fromuser)
and mm.timestamp > m.timestamp
)
and m.fromuser = 'user1' or m.touser = 'user1';
demo here.
It would probably be better, going forward, to flag conversations between two users as a particular conversation, then every message belongs to a conversation, and thus it becomes far easier to find conversations the user is involved in, and info about messages related to the conversation. Anyway.
Try this one instead. Ugh.
select m.*
from messages m
left join messages m2
on ((m.fromuser = m2.fromuser and m.touser = m2.touser)
or (m.fromuser = m2.touser and m.touser = m2.fromuser))
and m.timestamp < m2.timestamp
where (m.fromuser = 'user1' or m.touser = 'user1')
and m2.id is null;
It's likely to be superior to the not exists
version, even if i do manage to fix that one.
this fiddle actually works
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With