我的“用户”表是这样的
id name
1 UserA
2 UserB
3 UserC
4 UserD
我的“聊天”表就是这样
id text sentBy sentTo created
1 Hi UserB 1 2 2019-01-11
2 Hi 2 1 2019-01-12
3 Hi UserB 3 2 2019-01-13
4 Hello UserC 2 3 2019-01-14
5 Hello 3 2 2019-01-15
6 What u do 2 1 2019-01-16
7 Nothing 1 2 2019-01-17
8 Okay 2 1 2019-01-18
8 Hi UserA 3 1 2019-01-19
我想显示用户列表,该用户列表基于上一次msg与登录用户进行对话。 就像如果UserA登录系统,则列表应该像
userId userName text created
3 UserC Hi UserA 2019-01-19
2 UserB Okay 2019-01-19
我尝试使用联接查询和分组依据,但未成功。 我在Koa js中使用PostgreSQL。
答案 0 :(得分:1)
您可以使用DISTINCT ON
过滤掉对话中涉及的每个人的最新记录。
SELECT DISTINCT ON( involved) involved AS userid,
u.NAME AS username,
text,
created
FROM (SELECT c.*,
CASE sentby
WHEN 1 THEN sentto
ELSE sentby
END AS involved
FROM chats c
WHERE c.sentby = 1
OR c.sentto = 1) s
JOIN users u
ON s.involved = u.id
ORDER BY involved,
created DESC
如果要使用一般情况,可以将其转换为SQL类型的Postgres函数,并传递userid
作为参数,并使用它代替1。
答案 1 :(得分:1)
要获取参与$current_user
的最后一次对话的用户的完整列表,以及最后一条消息(发送或接收)及其日期(created
):
WITH u1 AS (SELECT id FROM users WHERE name = $current_user)
SELECT DISTINCT ON (userId) *
FROM (
SELECT u.id AS userId, u.name AS userName, c.text, c.created -- received
FROM u1
JOIN chats c ON c.sentBy = u1.id
JOIN users u ON u.id = c.sentTo
UNION ALL
SELECT u.id, u.name, c.text, c.created -- sent
FROM u1
JOIN chats c ON c.sentTo = u1.id
JOIN users u ON u.id = c.sentBy
) sub
ORDER BY userId, created DESC;
我分成两个UNIONed SELECT,以充分利用chats
上的两个索引-一个以sentTo
开头,一个以sentBy
开头。昨天刚刚更新了一个密切相关的答案:
关于DISTINCT ON
:
可以根据未公开的信息以各种方式进行优化。