そうそう、多くの人が遭遇しがちな「セットのグループ化」の典型的な問題...
複数のレコード (コメント) を 1 つの行 (イベント) に結合することについて話すとき、MySQL を使用して確実に (さまざまな量の行を考慮する場合のように) これを行う唯一の方法は、GROUP_CONCAT()
1 つまたは複数の行にまたがる情報を単一の区切り文字列。
と呼ばれる機能を使用して、情報をさまざまな量の実際の列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
SELECT
...の 4 番目の列を除いて、ここにあるものはすべてかなり簡単です。
最も内側には、 がありCONCAT()
ます。これにより、各コメントのフィールドが連結され、各コメントの複数の属性 (日付、実際のテキスト、おそらく ID など) を取得できるようになります。
aloneの後CONCAT()
、単一のコメントは次のようになります。
Lorem Ipsum dolor sit amet consecteur...:::2012-06-21 00:00:00
は、各属性を区切るために使用:::
する区切り文字の 1 つです。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
最初の 5 つのコメントのみが選択されます。コメントを最新順に並べたので、基本的には、各チケットで最新の 5 つのコメントのみを選択することになります。
次に、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
}
}
}
タイトルなどのフィールドにカンマが存在する可能性があり、スクリプトで文字列を間違った場所で区切らないようにするため、これらの特定の区切り記号を使用します。この誤った分離の可能性は、 を使用する場合の主な欠点の 1 つであるGROUP_CONCAT()
ため、フィールド値内に区切り文字が存在する可能性が低いことに基づいて、どの区切り文字を使用するのが最適かを決定する必要があります。