Giả sử người dùng có ID 1
và 3
, giống như bạn đã làm trong trò chơi, chúng tôi quan tâm đến thông báo có created_at
mới nhất và (sender_id, receiver_id)
là (1,3)
hoặc (3,1)
.
Bạn có thể sử dụng các loại hàng đặc biệt để tạo cú pháp ngắn gọn:
SELECT *
FROM messages
WHERE (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER BY created_at DESC
LIMIT 1;
Hoặc rõ ràng (và nhanh hơn một chút, cũng dễ sử dụng hơn với các chỉ mục):
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;
Cho tất cả cuộc trò chuyện của một người dùng
Đã thêm giải pháp theo yêu cầu trong bình luận.
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;
Cách tiếp cận ở đây là gấp người gửi / người nhận nước ngoài thành một cột để đơn giản hóa việc trích xuất hàng cuối cùng.
Giải thích chi tiết cho DISTINCT ON
trong câu trả lời có liên quan này:
Chọn hàng đầu tiên trong mỗi GROUP BY nhóm?
Ngoài ra, hãy xem xét trường hợp thử nghiệm được cải tiến và đơn giản hóa trong fiddle.