sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo obtener el último mensaje en cada conversación de un determinado usuario en SQL?

Suponiendo que los usuarios con ID 1 y 3 , como hiciste en el violín, estamos interesados ​​en el mensaje con el último created_at y (sender_id, receiver_id) siendo (1,3) o (3,1) .

Puede usar tipos de fila ad-hoc para acortar la sintaxis:

SELECT * 
FROM   messages 
WHERE  (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER  BY created_at DESC
LIMIT  1;

O explícitamente (y un poco más rápido, también más fácil de usar con índices):

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;

Para todos conversaciones de un usuario

Se agregó una solución según la solicitud en el comentario.

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;

El enfoque aquí es doblar remitente/receptor extranjero en una columna para simplificar la extracción de la última fila.

Explicación detallada de DISTINCT ON en esta respuesta relacionada:
¿Seleccionar la primera fila en cada grupo GROUP BY?

-> SQLfiddle actualizado .

Considere también el caso de prueba mejorado y simplificado en el violín.