Как получить последнюю запись в каждой группе с помощью GROUP BY?
Скажем, у меня есть таблица с именем messages
со столбцами:
id | from_id | to_id | subject | message | timestamp
Я хочу получить последнее сообщение от каждого пользователя, как вы видели бы в вашем входящем ящике FaceBook, прежде чем переходить в реальный поток.
Этот запрос, похоже, приближает меня к результату, который мне нужен:
SELECT * FROM messages GROUP BY from_id
Однако запрос дает мне самое старое сообщение от каждого пользователя, а не самое новое.
Я не могу понять этого.
Ответы
Ответ 1
Вы должны узнать последние значения timestamp
в каждой группе (подзапрос), а затем присоединить этот подзапрос к таблице -
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;
Ответ 2
Попробуйте это
SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc
Ответ 3
Просто дополняя то, что сказал Деварт, нижеприведенный код не упорядочивает в соответствии с вопросом:
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;
Предложение GROUP BY должно быть в основном запросе, так как нам нужно сначала изменить порядок "SOURCE", чтобы получить нужную "группировку":
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages ORDER BY timestamp DESC) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp GROUP BY t2.timestamp;
Привет,
Ответ 4
этот запрос возвращает последнюю запись для каждого Form_id:
SELECT m1.*
FROM messages m1 LEFT JOIN messages m2
ON (m1.Form_id = m2.Form_id AND m1.id < m2.id)
WHERE m2.id IS NULL;
Ответ 5
Это стандартная проблема.
Обратите внимание, что MySQL позволяет опускать столбцы из предложения GROUP BY, чего нет в стандартном SQL, но вы не получаете детерминированных результатов вообще при использовании средства MySQL.
SELECT *
FROM Messages AS M
JOIN (SELECT To_ID, From_ID, MAX(TimeStamp) AS Most_Recent
FROM Messages
WHERE To_ID = 12345678
GROUP BY From_ID
) AS R
ON R.To_ID = M.To_ID AND R.From_ID = M.From_ID AND R.Most_Recent = M.TimeStamp
WHERE M.To_ID = 12345678
Я добавил фильтр на To_ID
, чтобы соответствовать тому, что у вас есть. Запрос будет работать без него, но будет возвращать гораздо больше данных в целом. Условие не обязательно должно указываться как вложенным запросом, так и внешним запросом (оптимизатор должен автоматически отключать условие), но он не может нанести вреда повторению условия, как показано.
Ответ 6
Вам нужно заказать их.
SELECT * FROM messages GROUP BY from_id ORDER BY timestamp DESC LIMIT 1