En supposant que les utilisateurs avec l'ID 1
et 3
, comme vous l'avez fait dans le violon, nous sommes intéressés par le message avec le dernier created_at
et (sender_id, receiver_id)
étant (1,3)
ou (3,1)
.
Vous pouvez utiliser des types de lignes ad hoc pour raccourcir la syntaxe :
SELECT *
FROM messages
WHERE (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER BY created_at DESC
LIMIT 1;
Ou explicitement (et légèrement plus rapide, aussi plus facile à utiliser avec les index) :
SELECT *
FROM messages
WHERE (sender_id = 1 AND receiver_id = 3 OR
sender_id = 3 AND receiver_id = 1)
ORDER BY created_at DESC
LIMIT 1;
Pour tous conversations d'un utilisateur
Solution ajoutée selon la demande en commentaire.
SELECT DISTINCT ON (user_id) *
FROM (
SELECT 'out' AS type, id, receiver_id AS user_id, body, created_at
FROM messages
WHERE sender_id = 1
UNION ALL
SELECT 'in' AS type, id, sender_id AS user_id, body, created_at
FROM messages
WHERE receiver_id = 1
) sub
ORDER BY user_id, created_at DESC;
L'approche ici consiste à plier l'expéditeur / le destinataire étranger dans une colonne pour simplifier l'extraction de la dernière ligne.
Explication détaillée pour DISTINCT ON
dans cette réponse connexe :
Sélectionner la première ligne de chaque groupe GROUP BY ?
Considérez également le cas de test amélioré et simplifié dans le violon.