Maria Db - Получить последнее сообщение из списка всех сообщений, где user Id = variable - PullRequest
1 голос
/ 26 октября 2019

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

+----------------+---------------------+------+-----+---------+----------------+
| Field          | Type                | Null | Key | Default | Extra          |
+----------------+---------------------+------+-----+---------+----------------+
| id             | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| sender_user_id | int(11)             | NO   |     | NULL    |                |
| remote_user_id | int(11)             | NO   |     | NULL    |                |
| message        | longtext            | NO   |     | NULL    |                |
| read           | tinyint(4)          | NO   |     | NULL    |                |
| created_at     | timestamp           | YES  |     | NULL    |                |
| updated_at     | timestamp           | YES  |     | NULL    |                |
+----------------+---------------------+------+-----+---------+----------------+

Создать таблицу:

CREATE TABLE `messages` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `sender_user_id` int(11) NOT NULL,
  `remote_user_id` int(11) NOT NULL,
  `message` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
  `read` tinyint(4) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

Это то, что я пробовал до сих пор: SELECT sender_user_id, remote_user_id FROM messages m1 WHERE id = (SELECT MAX(m2.id) FROM messages m2 WHERE m1.sender_user_id = m2.sender_user_id AND m1.remote_user_id = m2.remote_user_id)

Что кажется близким, ноочевидно, не учитывает userId, который вы ищете, и иногда возвращает дубликаты, такие как:

MariaDB [snowdon]> SELECT sender_user_id, remote_user_id FROM messages m1 WHERE id = (SELECT MAX(m2.id) FROM messages m2 WHERE m1.sender_user_id = m2.sender_user_id AND m1.remote_user_id = m2.remote_user_id)
    -> ;
+----------------+----------------+
| sender_user_id | remote_user_id |
+----------------+----------------+
|              1 |              2 |
|              2 |              1 |
|              3 |              1 |
+----------------+----------------+
3 rows in set (0.00 sec)

Первая и вторая строки являются частью одной и той же конвекции, поэтому я хотел бы только самые последниечтобы получить результаты.

Может кто-нибудь помочь мне написать SQL?

Такс

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Я думаю, что вы хотите:

SELECT (CASE WHEN m.sender_user_id = ? THEN m.remote_user_id ELSE m.sender_user_id END) as other_user_id
FROM messages m
WHERE ? IN (m.sender_user_id, m.remote_user_id) AND
      m.id = (SELECT MAX(m2.id)
              FROM messages m2
              WHERE (m2.sender_user_id, m2.remote_user_id) IN 
                      ( (m.sender_user_id, m.remote_user_id),
                        (m.remote_user_id, m.sender_user_id)
                      )
             );
0 голосов
/ 26 октября 2019

У вас нет индекса, который бы поддерживал эффективный поиск. Таким образом, вы должны создать следующие два индекса: (sender_user_id, remote_user_id, id) и (remote_user_id, sender_user_id, id). Теперь, когда вы ищите последние сообщения от пользователя с идентификатором 123, вы можете использовать следующий запрос:

select m.*
from (
    select max(id) as id
    from (
        select remote_user_id as user_id, max(id) as id
        from messages
        where sender_user_id = 123
        group by remote_user_id
        union all
        select sender_user_id as user_id, max(id) as id
        from messages
        where remote_user_id = 123
        group by sender_user_id
    ) u
    group by user_id
) g
join messages m using(id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...