I have a messages system which doubles out as a message system and chat system, these are differentiated by a field called source.
I have the messages sections sorting and grouping properly however in the chat section it's not grouping these accordingly, please see my SQL below:
SELECT *
FROM messages
WHERE ( senderID = "1" OR receiverID = "1" )
AND source = "1"
GROUP BY receiverID, senderID
ORDER BY addedDate DESC LIMIT 10
So the result i am expecting is just one per match, ie one per conversation
however am getting two for some reason.
Thanks in advance
You are probably getting two answers per chat because you would have each person in both positions
ChatID Sender Receiver
1 1 2
2 2 1
3 1 2
4 2 1
So, you'll have a record grouped by
Sender / Receiver
1 2 and
2 1
I think what you are looking for is distinct people in the conversation where the above should be considered "ONE CHAT" regardless of the position they are in. To correct this, I would do something like...
select
PreQuery.*,
m2.Message,
m2.SenderID,
m2.ReceiverID
from
( SELECT
if( m.senderID < m.receiverID, m.senderID, m.receiverID ) as Person1,
if( m.senderID < m.receiverID, m.receiverID, m.senderID ) as Person2,
max( m.ID ) as LastMessageIDPerChat,
max( m.AddedDate ) as LastMessageDate
FROM
messages m
WHERE
m.Source = "1"
AND "1" IN ( SenderID, ReceiverID )
GROUP BY
Person1,
Person2
ORDER BY
m.AddedDate DESC
LIMIT 10 ) PreQuery
JOIN Messages m2
on PreQuery.LastMessageIDPerChat = m2.ID
This will ensure that whichever ID is lower will always be in the first position, and whichever person's ID is higher is always in second position to prevent false duplicates as described above.
Also note... GROUP BY is typically expecting all non-group by fields to be associated with some aggregation, otherwise, it will just grab the first instance of a record found with a qualifying condition. So, if you want to include same people in conversations on different days, you'll want to add "AddedDate" to the group by so it could have...
Person1 Person2 on 4/20
Person1 Person3 on 4/20
Person3 Person4 on 4/20
Person1 Person2 on 4/18
Person1 Person5 on 4/17
Person3 Person4 on 4/15
To get the status of who sent last, I had to wrap the query of paired people per conversation and get the last ID of that conversation. THEN, take that and re-join back to messages on that ID (if ID is actually the primary key ID of the messages table, adjust as needed). From the join, I can get the last message for the conversation AND who the sender ID and Receiver ID were for that transaction (and any other data you want from the now alias "m2" reference).
Are you sure your IDs aren't integers?
SELECT
receiverID,
senderID,
MAX(addedDate) as maxAddedDate
FROM
messages
WHERE
(
senderID = 1
OR receiverID = 1
)
AND source = 1
GROUP BY
receiverID,
senderID
ORDER BY
addedDate DESC
LIMIT 10
Check this out.
SELECT
receiverID,
senderID,
MAX(addedDate) as maxAddedDate
FROM messages
WHERE ( senderID = 1 OR receiverID = 1) AND source = 1
GROUP BY receiverID, senderID
ORDER BY addedDate DESC
You have not mentioned any aggregation for group by fields.
If your having multiple records according to any group by fields then what should happen?
you should have sum, count,...
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.