PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come ottenere l'ultimo messaggio in ogni conversazione di un determinato utente in SQL?

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?

-> SQLfiddle aggiornato .

Considera anche il test case migliorato e semplificato nel violino.