【问题标题】:MySQL: Return only last message in flat/conversation message tableMySQL:仅返回平面/对话消息表中的最后一条消息
【发布时间】:2011-07-27 22:53:22
【问题描述】:

我正在编写一个类似于 Facebook 的新消息系统的消息系统,其中两个用户之间的整个来回都被视为一次对话。 (与传统的电子邮件不同,传统电子邮件的每个回复都是单独的消息,或者 gMail 的对话,回复都在一个对话中,但您仍然可以在人与人之间进行多个对话)。 MySQL 版本是 5.0.92。

我一辈子都想不出如何为“收件箱”类型的视图编写查询。我只需要两个人之间的最后一条消息,would be easy,除了我不知道如何同时考虑“from_id”和“to_id”文件。

我的消息表如下所示:

突出显示的行是我希望返回的行(例如,不会返回 #2,因为用户 42 和 43 之间的最后一条消息是 #8)。是否有可能做到这一点?或者我最好使用两个查询(一个用于 to_id,一个用于 from_id)然后在 PHP 中解决它们?

感谢您的帮助

用于复制表的 SQL:

CREATE TABLE `messages` (
  `message_id` bigint(20) NOT NULL auto_increment,
  `to_id` int(11) NOT NULL,
  `from_id` int(11) NOT NULL,
  `message_sent` datetime NOT NULL,
  `message_body` text NOT NULL,
  `is_read` tinyint(1) NOT NULL default '0' COMMENT '0 = no, 1 = yes',
  PRIMARY KEY  (`message_id`),
  KEY `to` (`to_id`),
  KEY `is_read` (`is_read`),
  KEY `sent` (`message_sent`),
  KEY `from` (`from_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

INSERT INTO `messages` (`message_id`, `to_id`, `from_id`, `message_sent`, `message_body`, `is_read`) VALUES
(1, 42, 43, '2011-04-01 11:54:05', 'message 1', 0),
(2, 43, 42, '2011-04-01 11:54:05', 'message 1.2', 0),
(3, 42, 44, '2011-04-01 11:55:05', 'message 2', 1),
(4, 44, 42, '2011-04-01 11:55:02', 'message 2.1', 0),
(5, 43, 44, '2011-04-01 15:05:42', 'Message 3', 0),
(6, 44, 43, '2011-04-01 15:05:58', 'Message 3.1', 0),
(7, 42, 43, '2011-04-02 11:54:05', 'message x', 0),
(8, 43, 42, '2011-04-02 11:54:05', 'message x.2', 0);

编辑:对于那些感兴趣的人:

select `m`.`message_id` AS `message_id`,`m`.`to_id` AS `to_id`,`ut`.`name` AS `to_name`,`m`.`from_id` AS `from_id`,`uf`.`name` AS `from_name`,`m`.`message_sent` AS `message_sent`,`m`.`message_body` AS `message_body`,`m`.`is_read` AS `is_read` from ((`messages` `m` join `users` `ut` on((`m`.`to_id` = `ut`.`id`))) join `users` `uf` on((`m`.`from_id` = `uf`.`id`))) where `m`.`message_id` in (select max(`messages`.`message_id`) AS `MAX(message_id)` from `messages` group by greatest(`messages`.`to_id`,`messages`.`from_id`),least(`messages`.`to_id`,`messages`.`from_id`));

【问题讨论】:

    标签: mysql group-by


    【解决方案1】:
    SELECT MAX(message_id) FROM messages GROUP BY GREATEST(to_id, from_id), LEAST(to_id, from_id);
    

    如果你想要消息本身,你可以把它放在一个子选择中,或者把它变成一个视图并加入消息。

    【讨论】:

    • 我想这可能是我一直在寻找的答案,让我玩一下。谢谢尼尔!
    【解决方案2】:
    select * from messageTable 
    where message_id in 
    (select max(message_id) from messageTable where from_id = yourFromId and to_id = yourToId)
    

    更新

    select * 
    from messageTable 
    where (message_id in 
           (select max(message_id) from messageTable where from_id = yourFromId and to_id = yourToId))
        or (message_id in 
           (select max(message_id) from messageTable where from_id = yourToId and to_id = yourFromId)))
    

    【讨论】:

    • 谢谢约翰——这不是我想要的,因为这会将它限制在与一个人交谈的一侧
    • 正确...这将返回与 from_id 和 to_id 匹配的最后一个 message_id。
    • 我仍然不认为这就是我想要的,因为 from_id 和 to_id 在两个子查询中。我正在寻找最后一个条目无论哪种方式。所以:SELECT max(m.message_id) AS id, m.to_id, m.from_id, m.message_sent, m.message_body, m.is_read, m.message_id FROM messages m WHERE (m.to_id = 42) GROUP BY m。 from_id ORDER BY id DESC;然后使用 where m.from_id = 42 的相应子查询,然后呢?
    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多