查询同一查询中的帖子和标签

Ton*_*bet 9 php mysql activerecord join codeigniter

我有3个表与那些相关的领域

posts(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
Run Code Online (Sandbox Code Playgroud)

这看起来像,但即使是多个tags_map记录,它只返回一个,

如何在一个查询中返回所有内容?

-编辑-

我有点解决它,但需要PHP处理

$this->db->select('posts.*,group_concat(tags.name) as thetags');
Run Code Online (Sandbox Code Playgroud)

这将重新启动字段thethags ='tag1,tag2,tag3'

但我想在标签表上获得其他文件..

并且,例如:

$this->db->select('posts.*,group_concat(tags.name) as 'thetags',group_concat(tags.relevance) as 'therelevances');

我不确定我是否可以信任订单?

M K*_*aid 9

如果你不寻求group_concat解决方案会更好,因为它的字符长度不可靠,它的连接默认限制为1024个字符,但它可以增加,这在手动中定义,但你不能完全依赖于定义的限制,你可以在您的应用程序层(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();
Run Code Online (Sandbox Code Playgroud)

在上面的查询中我添加t.*了选择所有帖子及其相关标签现在在循环$currentParent中将有一个先前的帖子ID在循环检查如果它是一个相同的帖子然后显示其标签如果条件返回false然后它的新帖子显示帖子标题使用标记( h1),我已从两个表中选择了所有列,但是您应该只添加tags表中所需的列,如果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>'; 
    ...
}
Run Code Online (Sandbox Code Playgroud)

结果标记就像

<h1>Post title 1</h1>
    <p>tag 1</p>
    <p>tag 2</p>
<h1>Post title 2</h1>
    <p>tag 3</p>...
Run Code Online (Sandbox Code Playgroud)

如果你没有显示数据而你正在其他地方(web服务)使用它,那么仍然使用一个连接的查询并通过创建数组/对象来转换数据每个帖子都有一个相关标签的数组,如下所示

$posts =array();
foreach ($results as $post) {
 $posts[$post->id]['title'] = $post->title;
 $posts[$post->id]['tags'][] =array('id' => $tag->id ,'name' =>$post->name);
}
Run Code Online (Sandbox Code Playgroud)

还有另一种方法是高度不推荐获取帖子和循环获取标签现在运行查询此解决方案将工作但但将涉及不需要的查询,以便将为每个帖子执行额外的查询.

现在,如果您真的想坚持使用group_concat方法来回答您的问题,I'm not sure if I can trust the order?那么还有一种方法可以添加order by,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');
Run Code Online (Sandbox Code Playgroud)