Ах да, типичная проблема «группировка взаимозачетов», что многие люди, как правило, сталкиваются с ...
Когда мы говорим о присоединения нескольких записей (комментарии) на одну строку (событие), единственный способ надежно (как при учете переменных количеств строк) сделать это, используя MySQL, - использовать GROUP_CONCAT()
, который будет группировать информацию по одной или нескольким строкам в одну строку с разделителями.
Вы можете также информацию о группе в переменный размер фактических столбцов используя функцию под названием PIVOT
, но, к сожалению, PIVOT
не доступен в MySQL.
В любом случае вам понадобится логика приложения (взрывающаяся и т. Д.).) для форматирования и отображения подмножества комментариев для каждого билета.
Что касается SQL, вы можете сделать что-то вроде следующего:
SELECT
a.ticket_id,
a.ticket_title,
a.date_created,
SUBSTRING_INDEX(GROUP_CONCAT(CONCAT(LEFT(b.comment_txt, 150), '...', ':::', b.date_posted) ORDER BY b.date_posted DESC SEPARATOR '|||'), '|||', 5) AS comment_list
FROM
tickets a
LEFT JOIN
comments b ON a.ticket_id = b.ticket_id
WHERE
a.ticket_title LIKE '%search_term%'
GROUP BY
a.ticket_id
Все здесь довольно просто для 4-го столбца в SELECT
кроме ... так что давайте разбить его:
В большинстве случаев у нас есть CONCAT()
. Это означает, что он объединяет поля каждого комментария вместе, чтобы вы могли получать несколько атрибутов каждого комментария (например, дату, фактический текст и, возможно, идентификатор и т. Д.).
После одной только CONCAT()
, один комментарий может выглядеть примерно так:
Lorem Ipsum dolor sit amet consecteur...:::2012-06-21 00:00:00
:::
является одним из разделителей, которые вы бы explode()
на отделить каждый атрибут.
Перемещение наружу, то GROUP_CONCAT()
затем сцепляет каждый строку вместе. На данный момент мы в основном объединяем конкатенации. Кроме того, самые последние комментарии появляются в начале строки из-за ORDER BY b.date_posted
внутри функции.
Комментарий список может выглядеть следующим образом:
Lorem Ipsum dolor sit amet consecteur...:::2012-06-21 00:00:00|||Cras aliquam neque quam, eget facilisis nulla...:::2012-06-18 00:00:00
|||
является разделителем вы бы использовать, чтобы отделить каждый комментарий.
Переходя далее, SUBSTRING_INDEX
выбирает только первые пять комментариев. Поскольку мы заказывали комментарии по последним данным, это, по сути, только выбор пяти последних комментариев в каждом билете.
Затем в PHP коде, вы могли бы сделать примерно:
foreach($tickets as $ticket)
{
// First check if the ticket has comments. Value will be NULL if not.
if(!empty($ticket['comment_list']))
{
foreach(explode('|||', $ticket['comment_list']) as $comment)
{
$attributes = explode(':::', $comment);
$comment_preview = $attributes[0]; // Get first attribute
$date_posted = $attributes[1]; // Get second attribute
}
}
}
Я использую эти конкретные разделители, потому что запятые могут присутствовать в таких областях, как название, и т.д., и вы не хотите, чтобы ваш сценарий отделить строка в неправильных местах. Эта возможность ошибочного разделения является одним из основных недостатков использования GROUP_CONCAT()
, поэтому вы должны решить, какие разделители лучше всего использовать на основе маловероятности того, что они будут присутствовать в значениях полей.
Не могли бы вы разместить структуру ваших двух таблиц и какие поля в таблице 'comments' вы хотели бы получить для каждого билета? –