Se entendi bem sua exigência, você deseja obter a data mais recente da mensagem para cada conversa envolvendo um determinado usuário. Nesse caso, podemos agregar as conversas de um determinado usuário e reter a data da mensagem mais recente.
SELECT m1.*
FROM messages m1
INNER JOIN
(
SELECT LEAST(sender_id, recipient_id) AS first,
GREATEST(sender_id, recipient_id) AS second,
MAX(created_at) AS recent_date
FROM messages
WHERE sender_id = 2 OR recipient_id = 2
GROUP BY LEAST(sender_id, recipient_id),
GREATEST(sender_id, recipient_id)
) m2
ON LEAST(m1.sender_id, m1.recipient_id) = m2.first AND
GREATEST(m1.sender_id, m1.recipient_id) = m2.second AND
m1.created_at = m2.recent_date
Saída:
Explicação:
O desafio nessa consulta é encontrar uma maneira de agrupar conversas entre dois usuários. Eu usei o
LEAST/GREATEST
truque, que é uma maneira de tratar um 2 -> 4
e 4 -> 2
conversa como sendo logicamente a mesma coisa. Em seguida, usando GROUP BY
, podemos identificar a data de conversa mais recente para esse par de usuários que conversam. Portanto, a subconsulta na minha resposta acima encontra, para cada par de usuários, sem considerar qualquer ordem, esse par junto com sua data de conversa mais recente. Em seguida, juntamos esse resultado de volta às messages
tabela para trazer o texto da mensagem mais recente. Demonstração aqui: