Да приемем потребителите с ID 1
и 3
, както направихте във цигулката, ние се интересуваме от съобщението с последното created_at
и (sender_id, receiver_id)
е (1,3)
или (3,1)
.
Можете да използвате ad hoc типове редове, за да направите синтаксиса кратък:
SELECT *
FROM messages
WHERE (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER BY created_at DESC
LIMIT 1;
Или изрично (и малко по-бързо, също по-лесно за използване с индекси):
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;
За всички разговори на потребител
Добавено решение според заявка в коментар.
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;
Подходът тук е да сгънете чужд подател/получател в една колона, за да опростите извличането на последния ред.
Подробно обяснение за DISTINCT ON
в този свързан отговор:
Избиране на първия ред във всяка група GROUP BY?
Обърнете внимание и на подобрения и опростен тестов случай във цигулката.