选择表格中的最新记录(日期时间字段)

时间:2011-01-25 00:03:03

标签: mysql

我搜索了网站寻求帮助,但仍然在苦苦挣扎。这是我的表:

messages
========
id
thread_id
user_id
subject
body
date_sent

基本上我想检索每个thread_id的最新记录。我尝试过以下方法:

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

但是它给了我最古老的记录,而不是最新的记录!

任何人都可以提供建议吗?

编辑:表转储:

--
-- 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的所有消息,然后从那些检索到的消息中找到最新消息(每个thread_id)。

4 个答案:

答案 0 :(得分:34)

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;

让我知道它现在是否有效

答案 1 :(得分:4)

这是一个两站式的过程。首先找到每个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,则会同时选择它们(因为您无法判断哪个更新)

答案 2 :(得分:2)

这是一个非常古老的问题,但无论如何......

你的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

如果你想假设id总是随着时间的推移而增加,那么这可能会更好:

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

答案 3 :(得分:1)

从我所看到的,你的问题在于子查询。子查询实际上将从当前记录中提取最大date_sent字段,换句话说,因为外部查询一次遍历表一条记录,子查询“date_sent=(select max(date_sent)”中的两个date_sent字段将总是一样的。在显示特定thread_id的第一条记录之后,它不会显示该thread_id的任何其他记录,因为您按thread_id进行分组。这就是为什么,它将始终显示为每个thread_id输入的第一条记录。顺便说一句,它显示了为每个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子句,以从WHOLE表中提取每个thread_id的最大日期,而不仅仅是当前记录。此外,=必须替换为IN,因为子查询可能会导致多个记录。如果表在同一日期包含两个相同thread-id的记录,则只显示第一个。这是由外部查询中的第二个GROUP BY子句引起的。要在当天显示该thread_id的所有记录,请尝试:

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的最大日期的所有消息,并仍以正确的顺序显示线程。希望有所帮助。