【问题标题】:Mysql Query for a room based chat system. Build a list of all roomsMysql 查询基于房间的聊天系统。建立所有房间的列表
【发布时间】:2026-02-11 00:45:02
【问题描述】:

我可能需要一些有关基于房间的聊天应用程序的 mysql 查询的帮助。

查询需要找到用户所属的所有房间,并按最后一条消息提交到房间的日期对它们进行排序。

只有房间成员的用户才能阅读房间的消息。

这是一个“不工作”的代码,但它可能有助于了解查询应该做什么:

查询应该做什么: a) 创建用户所属的所有房间列表,按最后一条消息的日期排序 b)没有重复的房间(如果有多个不同日期的消息,下面的查询会多次列出房间......) c) 结果应包含 room_id、room_name 和来自该房间的最后一条消息的日期。

注意/提示:总会有一条消息存在。创建房间后,系统将自行添加第一条消息。 (每个房间的消息 1:“在“日期”创建房间”)。

有问题的查询:

SELECT DISTINCT cf.room_id, cf.date, cr.room_name
FROM cf_rooms_messages cf
INNER JOIN cf_rooms cr
ON cr.id = cf.room_id
WHERE EXISTS( 
  SELECT NULL 
  FROM cf_rooms_users 
  WHERE user_id = ? 
  AND room_id = cf.room_id 
)
ORDER BY cf.date
DESC LIMIT 0,10

表格布局:

/* this table keeps the room_id and the room_name */
CREATE TABLE IF NOT EXISTS `cf_rooms` (
  `id` int(12) NOT NULL,
  `room_name` varchar(255) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

/* this table keeps the messages submitted into the rooms */
CREATE TABLE IF NOT EXISTS `cf_rooms_messages` (
  `id` int(12) NOT NULL,
  `room_id` int(12) NOT NULL,
  `sender_uid` int(12) NOT NULL,
  `msg_text` text NOT NULL,
  `date` int(12) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=12 ;

/* this table contains the members of the rooms */
CREATE TABLE IF NOT EXISTS `cf_rooms_users` (
  `room_id` int(12) NOT NULL,
  `user_id` int(12) NOT NULL,
  `added_by_uid` int(12) NOT NULL,
  `added_on` int(12) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

结果应如下所示:

room_id |房间名 | last_message_date

感谢您的帮助。

【问题讨论】:

  • SELECT '' room_id, '' room_name, '' last_message_date

标签: php mysql subquery chat distinct


【解决方案1】:

您可以按用户和房间对结果进行分组,并从“房间”中的消息中获取最后(最大)日期。然后,您只需订购结果以按最后一条消息日期显示房间。

未测试,但应该类似于:

SELECT
    a.`user_id` as `user_id`,
    b.`room_name` as `room_name`,
    MAX(c.`date`) as `last_msg_date`
FROM `cf_rooms_users` a
JOIN `cf_rooms_rooms` b
ON a.`room_id` = b.`id`
JOIN `cf_rooms_messages` c
ON a.`user_id` = c.`sender_uid`
WHERE a.`id` = this_user_id
GROUP BY a.`user_id`, b.`room_name`
ORDER BY MAX(c.`date`) DESC, b.`room_name`;

this_user_id 替换为您要创建列表的用户的 ID。

【讨论】:

  • 谢谢。未知列 a.id。如果我将其更改为 a.user_id,则会引发以下错误:#1111 - Invalid use of group function
  • 我的错误。在 group by 子句中省略 MAX(c.date)
  • 我还建议使用时间戳而不是 int(12) 作为日期。这样您就可以按日期(忽略时间)范围、月份等进行选择。此外,将 ID 字段设置为 AUTO_INCREMENT 和主键。