group_concat
文字長が原因で信頼性が低いため、連結するデフォルトの制限は1024文字ですが、手動
ただし、定義された制限に完全に依存することはできません。代わりに、データをフェッチしているようにアプリケーションレイヤー(php)で処理でき、投稿とその関連タグを表示したい場所で、各投稿の投稿ごとに結合クエリを使用できます。複数のタグを含めることができるため、各投稿行に1つのタグがあり、同じ投稿の別の行に2番目のタグがあるため、結果セットには重複する投稿データが含まれます。結果をループすると、各投稿が1回だけ表示されます。チェックを追加する
$this->db->select('p.*,t.*');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->order_by('p.id asc,t.id asc');
$results = $this->db->get();
上記のクエリで、t.*
を追加しました ループ内にあるすべての投稿とそれに関連するタグを選択するには$currentParent
ループ内の前の投稿IDが同じ投稿であるかどうかを確認し、条件がfalseを返した場合はタグを表示し、新しい投稿はマークアップ(h1)を使用して投稿の見出しを表示します。両方のテーブルからすべての列を選択しましたが、必要なものだけを追加する必要がありますタグテーブルの列と、投稿テーブルとタグテーブルに同じ名前の列がある場合、クエリで異なるエイリアスでそれらを定義しました
$currentParent = false;
foreach ($results as $post) {
if ($currentParent != $post->id) {
echo '<h1>' . $post->title . '</h1>';
$currentParent = $post->id;
}
echo '<p>' . $post->name . '</p>'; /** here list tags info*/
echo '<p>' . $post->tag_other_details . '</p>';
...
}
結果のマークアップは次のようになります
<h1>Post title 1</h1>
<p>tag 1</p>
<p>tag 2</p>
<h1>Post title 2</h1>
<p>tag 3</p>...
データを表示しておらず、他の場所(Webサービス)で使用している場合でも、1つの結合クエリを使用し、配列/オブジェクトを作成してデータを変換します。各投稿には、以下のような関連タグの配列があります
$posts =array();
foreach ($results as $post) {
$posts[$post->id]['title'] = $post->title;
$posts[$post->id]['tags'][] =array('id' => $tag->id ,'name' =>$post->name);
}
強くお勧めしない別の方法があります クエリを実行して投稿を取得し、ループ内でタグを取得すると、このソリューションは機能しますが、不要なクエリが含まれるため、投稿ごとに追加のクエリが実行されます。
本当にgroup_concat
を使い続けたい場合 あなたの質問に答えるためのアプローチI'm not sure if I can trust the order?
order by
を追加する方法もあります group_concat
で 結果として連結されたタグが順序付けられ、2番目の列に同じ順序付け基準を設定できるようにします
$this->db->select('p.*,group_concat(t.name order by t.id) as thetags,
group_concat(t.relevance order by t.id) as therelevances');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->group_by('p.id');