我有3个表与那些相关的领域
帖子(id,title)
标签(id,name)
tags_map(id,id_post,id_tag)
我这样想:
$this->db->select('posts.*,tags.name');
$this->db->from('posts');
$this->db->join('tags_map', 'tags.id_post = posts.id');
$this->db->join('tags', 'tags.id = tags_map.id_tag');
$this->db->group_by('posts.id'); // I can comment this line and same result
这看起来像,但即使是多个tags_map记录,它只返回一个,
-编辑-
$this->db->select('posts.*,group_concat(tags.name) as thetags');
这将重新启动字段thethags =’tag1,tag2,tag3′
并且,例如:
$this-> db->选择(‘posts.*,group_concat(tags.name)为’thetags’,group_concat(tags.relevance)为’therelevances’);
我不确定我是否可以信任订单?
解决方法:
如果你不使用group_concat
解决方案会更好,因为它的字符长度不可靠,它有一个默认的1024个字符的限制来连接但它可以增加,这在manual中定义,但你不能完全依赖于定义的限制而不是你可以在您的应用程序层(PHP)中处理它,就像您正在获取数据一样,您想要显示帖子及其相关标签,您仍然可以使用您的连接查询和帖子,现在每个帖子可以有多个标签,所以结果集将有重复的帖子数据,因为每个帖子行将有一个标签,另一行具有相同的帖子将有第二个标签等现在当你循环结果显示每个帖子只有一次通过添加一些检查
$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)发布标题后,我选择了两个表中的所有列,但是您应该只添加标签表中所需的列,如果post和tag表具有相同名称的列,则在查询中使用不同的别名定义它们
$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服务)使用它,那么仍然使用一个连接的查询并通过创建数组/对象来转换数据每个帖子都有一个相关标签的数组,如下所示
$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方法来回答您的问题,我不确定我是否可以信任该订单?还有一种方法可以在group_concat中添加顺序,以便生成连接的标签,对于第二列,您可以放置相同的排序标准
$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');