问题描述
||
我正在创建一个类似于iPhone SMS系统的多收件人线程化消息传递系统(收件箱和发件箱都组合到一个显示器中,并且两个用户之间只能存在一个线程)。
使用senderid列(例如\“ 11 \”)和收件人列(例如\“,13,10,15,20,\”)存储邮件。为了存储多个收件人,我用逗号将它们分开,并使用\“%\” + \“,$ userid,\” + \“#\”调用查询该字段。这样做的问题是,它弄乱了LEFT JOIN,该连接将接收者ID连接到用户表(具有用户名)。
这是我当前的查询:
$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用户作为message上的receives.recipients(WITHOUT COMMAS)=收件人。 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个,则您可能需要编辑ѭ6。
警告:当表中有很多行时,这种类型的查询可能会很慢(甚至非常慢)。无法在ѭ7上使用索引,因此减慢了查询速度。因此,您最好现在考虑使用MessageRecipient
中间表规范化结构的选项。