Codeigniter多个连接查询

时间:2018-02-27 20:12:04

标签: sql codeigniter

$this->db->select('user_profile.user_id,story.story_id,display_name,story_title,synopsis,genre_name,tag_name,content_warning_name');
$this->db->from('story');
$this->db->join('user_profile', 'user_profile.user_id = story.user_id');
$this->db->join('story_genre', 'story_genre.story_id = story.story_id');
$this->db->join('story_tag', 'story_tag.story_id = story.story_id');
$this->db->join('story_content_warning', 'story_content_warning.story_id = story.story_id');
$this->db->where('story.story_id', $story_id);
$query = $this->db->get()->result();
$count = 0;
foreach($query as $row){
$story['author_id'] = $row->user_id;
$story['author_name'] = $row->display_name;
$story['story_title'] = $row->story_title;
$story['synopsis'] = $row->synopsis;
$story['genre'][$count] = $row->genre_name;
$story['tags'][$count] = $row->tag_name;
$count++;}

上面的代码有效,问题是它重复了4次(连接数量,巧合?我认为不是)。

类型将输出:动作浪漫幻想动作浪漫幻想动作浪漫幻想动作浪漫幻想

澄清:重复项来自查询本身循环x数量的连接表。我不知道我是否在编写查询时出错了但是它有效并且没有显示任何错误。

4个连接表= print_r($ query)将打印$ query 4次。

我过度了吗?我应该只连接只有1行值的表,而不是多行/数组(结果)的表。

防止重复。我可以设置一个限制变量作为查询结果的计数。

但最简单的方法是将数组键更改为名称。

$story['genre'][$row->genre_name] = $row->genre_name;
$story['tags'][$row->tag_name] = $row->tag_name;

上面的代码可以防止重复,即使查询运行了4次(由于4个连接,重复的条目只会覆盖自己,与选择的其他列相同)

2 个答案:

答案 0 :(得分:0)

看起来您主要是加入用户ID

$this->db->select('user_profile.user_id,distinct story.story_id,display_name,story_title,synopsis,genre_name,tag_name,content_warning_name');
$this->db->from('story');
$this->db->join('user_profile', 'user_profile.user_id = story.user_id');
$this->db->join('story_genre', 'story_genre.story_id = story.story_id');
$this->db->join('story_tag', 'story_tag.story_id = story.story_id');
$this->db->join('story_content_warning', 'story_content_warning.story_id = story.story_id');
$this->db->where('story.story_id', $story_id);
$query = $this->db->get();
if(!$query->num_rows())
        return false;
foreach($query->result() as $key => $story){
   $story['author_id'] = $row->user_id;
   $story['author_name'] = $row->display_name;
   $story['story_title'] = $row->story_title;
   $story['synopsis'] = $row->synopsis;
   $story['genre'][$key] = $row->genre_name;
   $story['tags'][$key] = $row->tag_name;
}

答案 1 :(得分:0)

一种方法是拆分您的查询 - 因为将1:nn:m关系组合起来并没有多大意义,因为您只想使用一个查询来执行此操作... (虽然我不确定story_content_warning所属的位置 - 如果它是1:n关系 - 您可以在第一个查询中加入它)

例如以下内容应该表明我的意思

$this->db
    ->select('user_profile.user_id,story.story_id,display_name,story_title,synopsis');
    ->from('story');
    ->join('user_profile', 'user_profile.user_id = story.user_id');
    ->where('story.story_id', $story_id);

$query = $this->db->get();

if ($query->num_rows() == 1)
{
    $objStory = $query->row();

    $objStory->genre = [];
    $objStroy->tags = [];


    $query = $this->db
        ->select('genre_name')
        ->from('story_genre')
        ->where('story_id', $objStory->story_id)
        ->get();

    if ($query->num_rows() > 0)
    {
        $objStory->genre = $query->result();
    }

    $query = $this->db
        ->select('tag_name')
        ->from('story_tag')
        ->where('story_id', $objStory->story_id)
        ->get();

    if ($query->num_rows() > 0)
    {
        $objStory->tags = $query->result();
    }

}