Search code examples
sqlpostgresqlselectdistinct

PostgreSQL select distinct by two columns


I have a table

senderId receiverId date
1 2 "2022-08-10T07:21:12.881Z"
2 1 "2022-08-10T07:28:12.881Z"
2 1 "2022-08-10T07:22:12.881Z"
1 2 "2022-08-10T07:25:12.881Z"

Current query

SELECT DISTINCT ON ("senderId", "receiverId") "sender"."id" AS "senderId", "receiver"."id" AS "receiverId", cm."createdAt" AS "createdAt" FROM "chat_message" "cm" LEFT JOIN "user" "sender" ON "sender"."id"="cm"."senderId"  LEFT JOIN "user" "receiver" ON "receiver"."id"="cm"."receiverId" WHERE "senderId" = 2 OR "receiverId" = 2 ORDER BY "senderId", "receiverId" ASC, cm."createdAt" DESC

Current result

senderId receiverId date
1 2 "2022-08-10T07:25:12.881Z"
2 1 "2022-08-10T07:28:12.881Z"

Expected result

senderId receiverId date
2 1 "2022-08-10T07:28:12.881Z"

So, I need to select only one row in this pair where the date is bigger


Solution

  • We can use a LEAST/GREATEST trick here along with DISTINCT ON:

    SELECT DISTINCT ON (LEAST(senderId, receiverId),
                        GREATEST(senderId, receiverId))
           LEAST(senderId, receiverId) AS senderId,
           GREATEST(senderId, receiverId) AS receiverId,
           createdAt
    FROM chat_message
    ORDER BY 1, 2, createdAt DESC;