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

时间:2015-08-01 21:51:30

标签: php mysql codeigniter join activerecord

我有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记录,它也只返回一个,

如何在一个查询中全部返回它们?

-edit -

我解决了它,但需要php处理

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

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

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

并且,例如:

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

我不确定我是否可以信任该命令?

3 个答案:

答案 0 :(得分:9)

如果你没有使用group_concat解决方案会更好,因为它的字符长度不可靠,它的默认限制为1024个字符可以连接,但可以增加{manual 3}}但你不能完全依赖定义的限制而不是你可以在你的应用程序层(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)它的新帖子显示帖子标题,我已经从两个表中选择了所有列,但是你应该只添加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>'; 
    ...
}

结果标记就像

<h1>Post title 1</h1>
    <p>tag 1</p>
    <p>tag 2</p>
<h1>Post title 2</h1>
    <p>tag 3</p>...

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

$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? ,您还可以在{{1}中添加order by这样生成的连接标签将被排序,对于第二列,您可以放置​​相同的排序标准

group_concat

答案 1 :(得分:0)

我认为应该像这样查询

/resources/sb/elements/SBMessages.properties.

使用join时,你应该使用一对多关系,在这种情况下,tags_map表作为联结表提供与帖子和标签表的多对一关系

答案 2 :(得分:-1)

请尝试以下代码:

$this->db->select('pt.*,group_concat(tg.name order by tg.id) as thetags,group_concat(tg.relevance order by tg.id) as therelevances');
$this->db->from('posts pt');
$this->db->join('tags_map tm', 'tg.id_post = pt.id');
$this->db->join('tags tg','tg.id =tm.id_tag');
$this->db->group_by('pt.id');