sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur får man det senaste meddelandet i varje konversation av en viss användare i SQL?

Förutsatt att användarna har ID 1 och 3 , som du gjorde i fiolen, är vi intresserade av meddelandet med den senaste created_at och (sender_id, receiver_id) är (1,3) eller (3,1) .

Du kan använda ad-hoc radtyper för att göra syntaxen kort:

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

Eller uttryckligen (och något snabbare, även lättare att använda med index):

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 alla en användares konversationer

Tillagd lösning enligt begäran i kommentar.

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;

Metoden här är att vika utländsk avsändare/mottagare i en kolumn för att förenkla extraheringen av den sista raden.

Detaljerad förklaring för DISTINCT ON i detta relaterade svar:
Välj första raden i varje GROUP BY-grupp?

-> Uppdaterad SQLfiddle .

Tänk också på det förbättrade och förenklade testfallet i fiolen.



  1. Sammanfoga en sträng och ett nummer i PostgreSQL

  2. Hur man lägger till just de distinkta värdena med SQLite Sum()

  3. Är dynamiska mysql-frågor med sql-escape lika säkra som förberedda uttalanden?

  4. Är COUNT(rovid) snabbare än COUNT(*)?