Подсчет количества непрочитанных сообщений для пользователя - PullRequest
0 голосов
/ 13 января 2019

Я достаточно много погуглил, но, похоже, не могу понять это правильно ...

У меня есть три таблицы:

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 голосов
/ 13 января 2019

Вы очень близки, но для получения непрочитанных сообщений вам нужно искать сообщения, созданные после / "превышающего" время посещения пользователя, например:

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')
0 голосов
/ 13 января 2019

Я думаю, вы довольно близки. Это должно делать то, что вы хотите:

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;

EDIT:

На основе комментария вы должны уметь:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...