первый. Вместо:
WHERE messages.recipients = '#' + ',$userid,' + '#'
Вы можете удалить начальные и конечные запятые и использовать:
WHERE FIND_IN_SET($userid, messages.recipients) > 0
Таким образом, у вас также может быть это условие для ЛЕВОГО СОЕДИНЕНИЯ:
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
промежуточной таблицы.