我已经进行了大量的谷歌搜索,但是我似乎无法正确地做到这一点。
我有三个表:
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;
但这不好。
答案 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')