Получение уникальных данных из MySQL

0

Я пытаюсь получить список последних сообщений. Здесь ситуация: когда сообщения отправляются с одинаковым временем, оператор сиквела выбирает все из них. Мне нужно только одно сообщение, последнее из каждого чата. С помощью @JuanCarlosOropeza (и его превосходной скрипки http://sqlfiddle.com/#!9/d506e/10, которую я немедленно включу в каждый вопрос, который я когда-либо задавал по этому вопросу), я получил нижеприведенное выражение.

SELECT *
FROM (  SELECT t.*,
               @rn := if(@friend = t.friend_id, 
                         @rn + 1,
                         if( @friend := t.friend_id, 1, 1)
                        ) as rn
        FROM ( 
                SELECT m.message, 
                       m.message_read,
                       m.message_date,
                       CASE WHEN m.sender = 4
                            THEN m.receiver
                            ELSE m.sender
                       END as friend_id,
                       CASE WHEN m.sender = 4
                            THEN p2.nickname
                            ELSE p1.nickname
                       END as name,
                       CASE WHEN m.sender = 4
                            THEN p2.image
                            ELSE p1.image
                       END as image
                FROM message as m
                JOIN profile as p1
                  ON m.sender = p1.user_id    -- sender
                JOIN profile as p2 
                  ON m.receiver = p2.user_id  -- receiver
                WHERE 4 IN (m.sender, m.receiver)
        ) as t
        CROSS JOIN ( SELECT @rn := 0, @friend := 0 ) as var
        ORDER BY t.friend_id, t.message_date desc
     ) q
WHERE q.rn = 1

Вышеприведенное сиквеловое выражение отлично справляется; однако есть один недостаток. ORDER BY t.friend_id, t.message_date desc не учитывает "точно такое же сообщение". Вполне возможно, что невозможно одновременно отправлять сообщения, но кто знает?

таблица друзей:

+----+-------+-------+---------+--------------+
ø id ø user1 ø user2 ø pending ø request_date ø
+----+-------+-------+---------+--------------+
ø  1 ø     4 ø     2 ø       0 ø 2018-05-09   ø
ø  2 ø     5 ø     2 ø       0 ø 2018-05-09   ø
ø  3 ø     1 ø     4 ø       0 ø 2018-05-09   ø
+----+-------+-------+---------+--------------+

таблица профилей:

+----+---------+----------------------+---------------+-------+
ø id ø user_id ø nickname             ø email         ø image ø
+----+---------+----------------------+---------------+-------+
ø  1 ø       1 ø Welcome to MathMatch ø [email protected] ø NULL  ø
ø  2 ø       2 ø user3                ø NULL          ø NULL  ø
ø  3 ø       3 ø USER4                ø NULL          ø NULL  ø
ø  4 ø       4 ø elokiller            ø NULL          ø NULL  ø
ø  5 ø       5 ø USER6                ø NULL          ø NULL  ø
+----+---------+----------------------+---------------+-------+

таблица сообщений:

+----+--------+----------+-----------+--------------+-----------------+---------------------+
ø id ø sender ø receiver ø message   ø message_read ø message_visible ø message_date        ø
+----+--------+----------+-----------+--------------+-----------------+---------------------+
ø  1 ø      4 ø        2 ø lulz      ø            1 ø               2 ø 2018-05-15 10:24:36 ø
ø  2 ø      1 ø        4 ø Hey Buddy ø            1 ø            NULL ø 2018-05-10 11:58:39 ø
ø  3 ø      2 ø        4 ø nooo      ø            1 ø               2 ø 2018-05-15 10:24:36 ø
ø  4 ø      4 ø        2 ø shut up   ø            1 ø               2 ø 2018-05-15 10:24:36 ø
+----+--------+----------+-----------+--------------+-----------------+---------------------+

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

+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø message   ø message_read ø message_date        ø friend_id ø name                 ø image ø rn   ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø Hey Buddy ø            1 ø 2018-05-10 11:58:39 ø         1 ø Welcome to MathMatch ø NULL  ø    1 ø
ø lulz      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
ø nooo      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+

Результат Я ожидаю:

+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø message   ø message_read ø message_date        ø friend_id ø name                 ø image ø rn   ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø Hey Buddy ø            1 ø 2018-05-10 11:58:39 ø         1 ø Welcome to MathMatch ø NULL  ø    1 ø
ø lulz      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+

Как вы видите, есть два сообщения от одного друга_ид, которое равно 2. Я просто хочу получить одно сообщение от этого друга. Спасибо, что нашли время. Любой комментарий будет полезен ~


Другой сценарий.

Текущая таблица сообщений:

+----+--------+----------+-----------+--------------+-----------------+---------------------+
| id | sender | receiver | message   | message_read | message_visible | message_date        |
+----+--------+----------+-----------+--------------+-----------------+---------------------+
|  1 |      4 |        2 | lulz      |            1 |               2 | 2018-05-15 10:24:36 |
|  2 |      1 |        4 | Hey Buddy |            1 |            NULL | 2018-05-10 11:58:39 |
|  3 |      2 |        4 | nooo      |            1 |               2 | 2018-05-15 10:24:36 |
|  4 |      4 |        2 | shut up   |            1 |               2 | 2018-05-15 10:24:36 |
|  5 |      4 |        2 | heha      |            1 |            NULL | 2018-05-15 10:36:11 |
|  6 |      1 |        4 | SUP MATE  |            1 |            NULL | 2018-05-15 11:04:24 |
+----+--------+----------+-----------+--------------+-----------------+---------------------+

текущая таблица результатов:

+-----------+--------------+---------------------+-----------+-------+-------+------+
| message   | message_read | message_date        | friend_id | name  | image | rn   |
+-----------+--------------+---------------------+-----------+-------+-------+------+
| Hey Buddy |            1 | 2018-05-10 11:58:39 |         1 | JUAN  | NULL  |    1 |
| nooo      |            1 | 2018-05-15 10:24:36 |         2 | user3 | NULL  |    1 |
+-----------+--------------+---------------------+-----------+-------+-------+------+

ожидать результата

+-----------+--------------+---------------------+-----------+-------+-------+------+
| message   | message_read | message_date        | friend_id | name  | image | rn   |
+-----------+--------------+---------------------+-----------+-------+-------+------+
| SUP MATE  |            1 | 2018-05-15 11:04:24 |         1 | JUAN  | NULL  |    1 |
| heha      |            1 | 2018-05-15 10:36:11 |         2 | user3 | NULL  |    1 |
+-----------+--------------+---------------------+-----------+-------+-------+------+
  • 0
    Что вы имеете в виду под "одним сообщением"? Какой из них должен быть найден, а какой следует игнорировать?
  • 0
    @AliSheikhpour Это не имеет большого значения, так как оба эти сообщения были отправлены одновременно. Исходя из приведенного выше результата, получение сообщения "lulz" имеет больше смысла. Если вы посмотрите на таблицу сообщений, там есть сообщение с «хеха», и это последнее; однако вышеприведенное утверждение полностью игнорирует этот факт.
Показать ещё 2 комментария
Теги:
database
select

1 ответ

0

Если вы добавите идентификатор в результирующую таблицу, вы можете выбрать последний идентификатор и группу по команде friend_id.

Предположим, что вы можете создать представление о видах ниже

CREATE TABLE IF NOT EXISTS 'MESSAGES' (
  'id' int(6) unsigned NOT NULL,
  'friend_id' int(3) unsigned NOT NULL,
  'message_time' varchar(200) NOT NULL,
  PRIMARY KEY ('id')
) DEFAULT CHARSET=utf8;
INSERT INTO 'MESSAGES' ('id', 'friend_id', 'message_time') VALUES
  ('1', '1', '2018-05-10 11:58:39'),
  ('2', '2', '2018-05-15 10:24:36'),
  ('3', '2', '2018-05-15 10:24:36');

Затем вы выбираете сообщения с максимальным временем, сгруппированным по идентификатору друга, а затем вы выбираете сообщение с максимальным id в нем. Этого можно достичь со следующим SQL.

SELECT MESSAGES.id, MESSAGES.friend_id, MESSAGES.message_time FROM

(
  SELECT max(id) as id, friend_id FROM
  (SELECT id,
          m.friend_id,
          m.message_time
   FROM MESSAGES m
   JOIN
     (SELECT friend_id,
             MAX(message_time) AS message_time
      FROM MESSAGES
      GROUP BY friend_id) mx ON mx.friend_id = m.friend_id
   AND mx.message_time = m.message_time) b GROUP BY friend_id
) a JOIN 
   MESSAGES on a.id = MESSAGES.id ;

Получение результатов по таблице СООБЩЕНИЙ в вышеуказанном запросе должно быть достаточно простым, так как вы сделали что-то похожее на ваш вопрос.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню