在 MySQL(消息系统)中返回多个收件人姓名
Posted
技术标签:
【中文标题】在 MySQL(消息系统)中返回多个收件人姓名【英文标题】:Returning multiple recipients names in MySQL (messaging system) 【发布时间】:2011-04-12 19:27:04 【问题描述】:我正在创建一个类似于 iPhone SMS 系统的多收件人线程消息系统(其中收件箱和发件箱合并为一个显示,两个用户之间只能存在一个线程)。
使用发件人列(例如“11”)和收件人列(例如“,13,10,15,20”)存储消息。为了存储多个收件人,我用逗号将它们分开,并使用 "%" + ",$userid," + "#" 调用查询该字段。这样做的问题是它弄乱了将接收者连接到用户表(具有用户名)的 LEFT JOIN。
这是我当前的查询:
$sql =
"SELECT DISTINCT CASE
WHEN $userid != senderid THEN senderid ELSE recipients END someid,
CASE WHEN 13 != senderid THEN senders.username ELSE receivers.username END somename,
messages.body,
messages.time
FROM messages
LEFT JOIN users AS senders ON messages.senderid = senders.id
LEFT JOIN users AS receivers ON messages.recipients = receivers.id
WHERE messages.recipients = '#' + ',$userid,' + '#'
OR messages.senderid = $userid
ORDER BY messages.time";
这是我想做的:
如果收件人中只有一个收件人 id(内容看起来像“,id”,则删除 id 周围的逗号以找到发件人名称(LEFT JOIN users AS receivers ON messages.recipients(WITHOUT COMMAS ) = receivers.id。
如果收件人中有多个收件人 id(内容看起来像“,id,id2,id3”等),则以某种方式提取与该 ID 对应的所有名称并将结果存储为类似于如下:sendername = "Name1, Name2, Name3";.
有人知道我将如何处理这个问题吗?也许是子查询?非常感谢您的帮助。
【问题讨论】:
【参考方案1】:第一。而不是:
WHERE messages.recipients = '#' + ',$userid,' + '#'
你可以去掉开始和结束的逗号并使用:
WHERE FIND_IN_SET($userid, messages.recipients) > 0
所以你也可以为 LEFT JOIN 设置这个条件:
LEFT JOIN users AS receivers
ON FIND_IN_SET(receivers.id, messages.recipients) > 0
然后按消息分组并将名称与GROUP_CONCAT()
连接起来。
类似这样的:
SELECT senders.name AS senderName
, messages.body
, messages.time
, GROUP_CONCAT( receivers.name
ORDER BY receivers.id
SEPARATOR ','
)
AS receiversNames
FROM messages
LEFT JOIN users AS senders
ON messages.senderid = senders.id
LEFT JOIN users AS receivers
ON FIND_IN_SET(receivers.id, messages.recipients) > 0
GROUP BY messages.id
ORDER BY messages.time
将为您提供所有邮件,其中发件人姓名和收件人姓名连接在一起。
我猜每条消息都恰好有 1 个(或零个)发件人。如果没有,并且某些邮件的发件人超过 1 个,那么您可能需要编辑 GROUP BY
。
警告:当表中有很多行时,这种类型的查询可能会很慢(甚至非常慢)。 messages.recipients
上不能使用索引,因此会减慢查询速度。因此,您现在最好考虑使用MessageRecipient
中间表规范化您的结构的选项。
【讨论】:
这看起来很棒,非常感谢。试着出去,我会回复你的! ypercube,我现在正在阅读规范化,但您的意思是创建一个 MessageRecipient 表,您基本上可以在其中“标记”用户到消息? 是的,因此您的messages.recipients
字段将被该表中的许多行替换(消息中的每个收件人一个)
这是一个更好的结构吗?我标准化了我的数据库。 pastebin.com/UGdKsx14
是的。 messages_recipients
可以有一个复合主键 (messageid, userid)
以上是关于在 MySQL(消息系统)中返回多个收件人姓名的主要内容,如果未能解决你的问题,请参考以下文章