MySQL:仅返回平面/对话消息表中的最后一条消息

发布于 2024-10-29 09:18:43 字数 2231 浏览 1 评论 0原文

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

我一生都无法弄清楚如何编写“收件箱”类型视图的查询。我所需要的只是两个人之间的最后一条消息,这很容易< /a> 但我不知道如何考虑“from_id”和“to_id”字段。

我的消息表如下所示: messages table

突出显示的行是我想要返回的行(#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`));

I'm writing a messaging system like Facebook's new Messages system, where the entire back and forth between two users is considered one conversation. (As opposed to traditional email where each reply is a separate message or gMail's conversations where replies are all together in a conversation but you can still have multiple conversations between people). MySQL version is 5.0.92.

I can't for the life of me figure out how to write the query for the "inbox" type view. All I would need is the very last message between two people, which would be easy except I don't know how to take into account both the "from_id" and "to_id" fileds.

My messages table looks like this:
messages table

The highlighted rows are the ones I'd like returned (#2 wouldn't be returned because the last message between users 42 and 43 is #8, for instance). Is it possible to do this? Or would I be better off using two queries (one for to_id and one for from_id) then working them out in PHP?

Thanks for your help

SQL to replicate the table:

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);

Edit: for those interested:

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`));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰◇生如夏花灿烂 2024-11-05 09:18:43
SELECT MAX(message_id) FROM messages GROUP BY GREATEST(to_id, from_id), LEAST(to_id, from_id);

如果您想要消息本身,您可以将其放入子选择中,或者将其转换为视图并将其与消息连接起来。

SELECT MAX(message_id) FROM messages GROUP BY GREATEST(to_id, from_id), LEAST(to_id, from_id);

If you want the messages themselves you can put this in a subselect, or turn it into a view and join it with messages.

打小就很酷 2024-11-05 09:18:43
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)))
select * from messageTable 
where message_id in 
(select max(message_id) from messageTable where from_id = yourFromId and to_id = yourToId)

Updated

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)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文