Я пытаюсь получить список последних сообщений. Здесь ситуация: когда сообщения отправляются с одинаковым временем, оператор сиквела выбирает все из них. Мне нужно только одно сообщение, последнее из каждого чата. С помощью @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 |
+-----------+--------------+---------------------+-----------+-------+-------+------+
Если вы добавите идентификатор в результирующую таблицу, вы можете выбрать последний идентификатор и группу по команде 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 ;
Получение результатов по таблице СООБЩЕНИЙ в вышеуказанном запросе должно быть достаточно простым, так как вы сделали что-то похожее на ваш вопрос.