PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como obter a mensagem mais recente em cada conversa de um determinado usuário no SQL?


Assumindo os usuários com ID 1 e 3 , como você fez no violino, estamos interessados ​​na mensagem com a última created_at e (sender_id, receiver_id) sendo (1,3) ou (3,1) .

Você pode usar tipos de linha ad hoc para tornar a sintaxe curta:
SELECT * 
FROM   messages 
WHERE  (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER  BY created_at DESC
LIMIT  1;

Ou explicitamente (e um pouco mais rápido, também mais fácil de usar com í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 conversas de um usuário


Solução adicionada conforme solicitação no comentário.
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;

A abordagem aqui é dobrar o remetente/receptor estrangeiro em uma coluna para simplificar a extração da última linha.

Explicação detalhada para DISTINCT ON nesta resposta relacionada:
Selecionar a primeira linha em cada grupo GROUP BY?

-> SQLfiddle atualizado .

Considere também o caso de teste aprimorado e simplificado no violino.