Выберите последнюю запись в таблице (поле даты и времени)
Я искал сайт для помощи, но все еще борется. Вот моя таблица:
messages
========
id
thread_id
user_id
subject
body
date_sent
В основном я хочу получить последнюю запись для каждого потока_ид. Я пробовал следующее:
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages
WHERE user_id=1 AND date_sent=(select max(date_sent))
GROUP BY thread_id
ORDER BY date_sent DESC
НО это дает мне самые старые записи, а не самые новые!
Любой, кто может посоветовать?
EDIT: Дамп таблицы:
--
-- Table structure for table `messages`
--
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(10) unsigned NOT NULL auto_increment,
`thread_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`body` text NOT NULL,
`date_sent` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;
--
-- Dumping data for table `messages`
--
INSERT INTO `messages` (`id`, `thread_id`, `user_id`, `body`, `date_sent`) VALUES
(1, 1, 1, 'Test Message', '2011-01-20 00:13:51'),
(2, 1, 6, 'Test Message', '2011-01-20 01:03:50'),
(3, 1, 6, 'Test Message', '2011-01-20 01:22:52'),
(4, 1, 6, 'Test Message', '2011-01-20 11:59:01'),
(5, 1, 1, 'Test Message', '2011-01-20 11:59:22'),
(6, 1, 6, 'Test Message', '2011-01-20 12:10:37'),
(7, 1, 1, 'Test Message', '2011-01-20 12:10:51'),
(8, 2, 6, 'Test Message', '2011-01-20 12:45:29'),
(9, 1, 6, 'Test Message', '2011-01-20 13:08:42'),
(10, 1, 1, 'Test Message', '2011-01-20 13:09:49'),
(11, 2, 1, 'Test Message', '2011-01-20 13:10:17'),
(12, 3, 1, 'Test Message', '2011-01-20 13:11:09'),
(13, 1, 1, 'Test Message', '2011-01-21 02:31:43'),
(14, 2, 1, 'Test Message', '2011-01-21 02:31:52'),
(15, 4, 1, 'Test Message', '2011-01-21 02:31:57'),
(16, 3, 1, 'Test Message', '2011-01-21 02:32:10'),
(17, 4, 6, 'Test Message', '2011-01-20 22:36:57'),
(20, 1, 6, 'Test Message', '2011-01-20 23:02:36'),
(21, 4, 1, 'Test Message', '2011-01-20 23:17:22');
РЕДАКТИРОВАТЬ: Извинения. Возможно, у меня здесь немного запутались - в основном, я хочу получить все сообщения для данного user_id, затем найдите последнее сообщение (за поток_ид) из этих полученных сообщений.
Ответы
Ответ 1
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages WHERE date_sent IN (
SELECT MAX( date_sent )
FROM messages WHERE user_id =6 GROUP BY thread_id
)
ORDER BY thread_id ASC , date_sent DESC;
Сообщите мне, если он работает сейчас
Ответ 2
Это процесс с двумя остановками. Сначала найдите самые новые даты для каждого thread_id
. Затем выберите записи, которые имеют эти даты и соответствуют thread_id
s
SELECT t.id, t.thread_id, t.user_id, t.body, t.date_sent
FROM messages AS t
CROSS JOIN (
SELECT thread_id, MAX(date_sent) AS date_sent FROM messages WHERE user_id = 1 GROUP BY thread_id
) AS sq
USING (thread_id, date_sent)
Обратите внимание, что если два (или более) messages
имеют одинаковые date_sent
и одинаковые thread_id
, они оба будут выбраны (потому что вы не можете определить, какая из них более новая)
Ответ 3
Из того, что я вижу, ваша проблема заключается в подзапросе. Подзапрос фактически будет извлекать максимальное поле date_sent из текущей записи, другими словами, поскольку внешний запрос пересекает запись по одной таблице за раз, когда два поля date_sent в подзапросе "date_sent=(select max(date_sent)
" всегда будут тоже самое. После того, как он отображает первую запись для определенного потока_ид, он не отображает никаких других записей для этого потока_ид, поскольку вы группируете thread_id. Поэтому всегда будет отображаться первая запись, введенная для каждого thread_id. BTW, он показывает первую запись, введенную для каждого потока thread_id, а не самую раннюю запись date_sent. Ваш результат зависит от местоположения записи в вашей таблице, а не от значения date_sent. Не уверен, правильно ли я это объяснил, но в любом случае, чтобы исправить вашу проблему, попробуйте:
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages
WHERE user_id=1 AND date_sent IN (select max(date_sent) from messages GROUP BY thread_id)
GROUP BY thread_id
ORDER BY date_sent DESC;
Во-первых, подзапрос должен иметь предложение FROM
и предложение GROUP BY
, чтобы вытащить максимальные даты в thread_id из таблицы WHOLE, а не только текущую запись. Кроме того, =
необходимо заменить на IN
, поскольку подзапрос может привести к нескольким записям. Если таблица содержит две записи одного и того же идентификатора потока в одну и ту же дату, будет отображаться только первая. Это вызвано вторым предложением GROUP BY
во внешнем запросе. Чтобы отобразить все записи этого потока в этом дне, попробуйте:
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages
WHERE user_id =1 AND date_sent IN (SELECT MAX( date_sent ) FROM messages GROUP BY thread_id)
ORDER BY thread_id ASC , date_sent DESC;
Удалив второе предложение GROUP BY
и добавляя предложение ORDER BY
, вы можете показать все сообщения за эту максимальную дату для каждого потока thread_id и по-прежнему отображать потоки в правильном порядке. Надеюсь, что это поможет.
Ответ 4
Это действительно старый вопрос, но в любом случае...
Ваше предложение where недостаточно специфично, и использование date_sent для выбора правильной записи просто неверно. Попробуйте следующее:
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages
WHERE id=(
select m2.id from messages m2
where messages.thread_id=m2.thread_id
order by date_sent desc limit 1)
ORDER BY date_sent DESC
Если вы хотите предположить, что идентификатор всегда увеличивается с течением времени, это, вероятно, будет работать лучше:
SELECT id, thread_id, user_id, subject, body, date_sent
FROM messages
WHERE id in (
select max(m2.id) from messages m2 group by m2.thread_id)
ORDER BY date_sent DESC