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?
Beachten Sie auch den verbesserten und vereinfachten Testfall in der Geige.