Assumendo gli utenti con ID 1
e 3
, come hai fatto tu nel violino, siamo interessati al messaggio con l'ultimo created_at
e (sender_id, receiver_id)
essendo (1,3)
o (3,1)
.
Puoi utilizzare tipi di riga ad hoc per rendere la sintassi breve:
SELECT *
FROM messages
WHERE (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER BY created_at DESC
LIMIT 1;
Oppure in modo esplicito (e leggermente più veloce, anche più facile da usare con gli indici):
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;
Per tutti conversazioni di un utente
Aggiunta soluzione come da richiesta in commento.
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'approccio qui è piegare mittente/destinatario straniero in una colonna per semplificare l'estrazione dell'ultima riga.
Spiegazione dettagliata per DISTINCT ON
in questa risposta correlata:
Seleziona la prima riga in ogni gruppo GROUP BY?
Considera anche il test case migliorato e semplificato nel violino.