计算用户的未读消息数

时间:2019-01-13 16:48:47

标签: sql postgresql join

我已经进行了大量的谷歌搜索,但是我似乎无法正确地做到这一点。

我有三个表:

comm_messages:

- room_id:integer
- created_at:datetime

comm_visitors:

- room_id:integer
- user_id:integer
- updated_at:datetime

我想查找给定的user_id,那里有几则新消息(用户访问房间后创建的消息)?

示例

如果我有这种数据:

comm_messages:

+---------+------------------+
| room_id |    created_at    |
+---------+------------------+
|   1     |   20.11.2018     |
|   1     |   20.12.2018     |
|   2     |   21.12.2018     |
|   3     |   24.12.2018     |
|   4     |   19.05.2018     |
+---------+------------------+

comm_visitors:

+---------+---------+------------+
| user_id | room_id | updated_at |
+---------+---------+------------+
|    1    |    1    | 03.11.2018 |
|    1    |    3    | 25.12.2018 |
|    1    |    4    | 11.05.2018 |
|    2    |    1    | 01.01.2019 |
|    2    |    2    | 03.11.2018 |
|    2    |    4    | 03.11.2018 |
+---------+---------+------------+

对于user_id = 1我应该得到3,对于user_id = 2我应该得到2

我当前的尝试一直围绕着这样的事情:

SELECT COUNT(comm_messages.id) 
  FROM comm_messages LEFT JOIN comm_visitors 
   ON comm_messages.room_id = comm_visitors.room_id 
  WHERE comm_visitors.user_id = 1 
   AND comm_visitors.updated_at > comm_messages.updated_at;

但这不好。

2 个答案:

答案 0 :(得分:1)

我认为您非常接近。这应该做您想要的:

SELECT COUNT(*) 
FROM (SELECT v.user_id, v.room_id, MAX(v.updated_at) as last_visit
      FROM comm_visitors v
      WHERE v.user_id = 1
      GROUP BY v.user_id, v.room_id
     ) v JOIN
     comm_messages m
     ON m.room_id = v.room_id AND
        v.last_visit > m.updated_at;

编辑:

根据评论,您应该可以:

SELECT COUNT(*) 
FROM comm_visitors v JOIN
     comm_messages m
     ON m.room_id = v.room_id AND
        v.updated_at > m.updated_at
WHERE v.user_id = 1

答案 1 :(得分:0)

您非常接近,但是要获取未读消息,您需要查找在/“大于”用户访问时间之后创建的消息,如下所示:

select count(1)
from comm_visitors v
join comm_messages  m on v.room_id = m.room_id 
 --only include messages created _after_ the last visit
 and v.updated_at < m.created_at
where v.user_id = 1

如果要在用户从未访问过的房间中包含未读邮件,则可以使用以下方式:

select count(1)
from comm_messages m
left join comm_visitors v on v.room_id = m.room_id and v.user_id = 1
where m.created_at > coalesce(v.updated_at, '1900-01-01')