获取参与对话的用户列表

时间:2019-03-02 03:15:19

标签: sql postgresql

我的“用户”表是这样的

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。

2 个答案:

答案 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 

Demo

如果要使用一般情况,可以将其转换为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

可以根据未公开的信息以各种方式进行优化。