PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie bekomme ich die neueste Nachricht in jeder Konversation eines bestimmten Benutzers in SQL?

Angenommen die Benutzer mit der ID 1 und 3 , wie Sie es in der Geige getan haben, interessiert uns die Nachricht mit dem neuesten created_at und (sender_id, receiver_id) ist (1,3) oder (3,1) .

Sie können Ad-hoc-Zeilentypen verwenden, um die Syntax kurz zu machen:

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

Oder explizit (und etwas schneller, auch einfacher mit Indizes zu verwenden):

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;

Für alle Unterhaltungen eines Benutzers

Lösung gemäß Anfrage im Kommentar hinzugefügt.

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;

Der Ansatz besteht hier darin, fremde Sender/Empfänger in eine Spalte zu falten, um die Extraktion der letzten Zeile zu vereinfachen.

Ausführliche Erklärung für DISTINCT ON in dieser verwandten Antwort:
Erste Zeile in jeder GROUP BY-Gruppe auswählen?

-> SQLfiddle aktualisiert .

Beachten Sie auch den verbesserten und vereinfachten Testfall in der Geige.