MySQL查询 - 有更好的方法吗?

时间:2013-02-03 08:21:19

标签: php mysql codeigniter

在我的博客上,我有一个功能可以统计每月发布的博客数量,这些功能可以在子菜单中显示。

按年份循环,然后按月循环另一个嵌套循环。每次运行此查询以计算每月发布的文章数量。

这是查询:

Select * from DM_blog blog where  blog.id IN 
    ( SELECT entry_id FROM DM_tags_target tagstarget WHERE tagstarget.parent_id IN 
    ( SELECT id FROM DM_tags tags WHERE tags.tag = '".$data['page']['id']."' AND tags.type = 'blog_target' )) AND blog.publish < '".date("Y-m-d H:i:s")."' and blog.status = '0'  and YEAR(blog.publish) = '".$year."' and MONTH(blog.publish) = '".$month."'"

有更好的方法吗?我可以一次完成所有月份,而不是每年进行12次查询吗?完整的代码在这里:

$this->benchmark->mark('blog_submenu_start');
    $dates = $this->blog_model->menu_dates($data);
    if($dates['years']){
        $i = 0;
        foreach($dates['years'] as $year){
            if($data['segments']['modal'] == $year['YEAR(blog.publish)']){
                $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['class'] = 'selected';
                $selected = true;
            }else if(date("Y") == $year['YEAR(blog.publish)'] && $selected == false){
                $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['class'] = 'selected';
                $selected = true;
            }

            // find the start month
            if($dates['first_entry'][0]['YEAR(blog.publish)'] == $year['YEAR(blog.publish)']){
                if($dates['first_entry'][0]['MONTH(blog.publish)'] < 2){
                    $limit_s['start'] = '1';
                    $limit_s['end'] = 13;
                }else{
                    $limit_s['start'] = $dates['first_entry'][0]['MONTH(blog.publish)'];
                    $limit_s['end'] = 12;
                }
            }else{
                $limit_s['start'] = 1;
                $limit_s['end'] = 13;
            }
            // run through the months
            $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_start');
            for($x=$limit_s['start'];$x<=$limit_s['end'];$x++){
                $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_start');
                $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_mysql_start');
                $count = $this->blog_model->month_count($year['YEAR(blog.publish)'],$x,$data);
            $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_mysql_end');
                if($last == false){
                    $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_selected_start');
                    if($data['segments']['modal'] == $year['YEAR(blog.publish)'] and $data['segments']['para_one'] == $x){
                        $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['class'] = 'selected';
                    }
                    $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_selected_end');
                    $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_assign_start');
                    $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['month'] = $x;
                    $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['display_full'] = date('F',strtotime($year['YEAR(blog.publish)'].'-'.$x.'-01')); 
                    $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['display_short'] = date('M',strtotime($year['YEAR(blog.publish)'].'-'.$x.'-01')); 
                    $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['count'] = $count;
                    $data['date_submenu']['year'][$year['YEAR(blog.publish)']]['months'][$x]['sef'] = $year['YEAR(blog.publish)'].'/'.$x.'/';
                    $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_assign_end');
                    if(date("Y") == $year['YEAR(blog.publish)'] and date("m") == $x || date("n") == $x){
                        $last = true;
                    } // end date
                    $i++;
                    $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_'.$x.'_end');
                } // end last false
            } // end for
            $this->benchmark->mark('blog_submenu_dates_'.$year['YEAR(blog.publish)'].'_end');
        }
    }
    $this->benchmark->mark('blog_submenu_end');

$ this-&gt; blog_model-&gt; month_count - 此功能如下:

function month_count($year,$month,$data=false){
    $query = $this->db->query("Select * from DM_blog blog where  blog.id IN 
    ( SELECT entry_id FROM DM_tags_target tagstarget WHERE tagstarget.parent_id IN 
    ( SELECT id FROM DM_tags tags WHERE tags.tag = '".$data['page']['id']."' AND tags.type = 'blog_target' )) AND blog.publish < '".date("Y-m-d H:i:s")."' and blog.status = '0'  and YEAR(blog.publish) = '".$year."' and MONTH(blog.publish) = '".$month."'");
    return $query->num_rows(); 
}

2 个答案:

答案 0 :(得分:1)

您可以添加group by子句,按年份和月份对结果进行分组。

Select * from DM_blog blog where  blog.id IN 
( SELECT entry_id FROM DM_tags_target tagstarget WHERE tagstarget.parent_id IN 
( SELECT id FROM DM_tags tags WHERE tags.tag = '".$data['page']['id']."' AND tags.type =     'blog_target' )) AND blog.publish < '".date("Y-m-d H:i:s")."' and blog.status = '0'  GROUP BY     YEAR(blog.publish), MONTH(blog.publish)

答案 1 :(得分:0)

您可以使用GROUP BY表达式:

SELECT id, YEAR(blog.publish), MONTH(blog.publish)
  FROM DM_blog blog 
 WHERE  blog.id IN 
( SELECT entry_id 
    FROM DM_tags_target tagstarget 
   WHERE tagstarget.parent_id IN 
         ( SELECT id 
             FROM DM_tags tags
            WHERE tags.tag = '".$data['page']['id']."' 
              AND tags.type = 'blog_target' 
          )
) 
AND blog.publish < '".date("Y-m-d H:i:s")."' 
AND blog.status = '0'  
GROUP BY YEAR(blog.publish), MONTH(blog.publish)

它将为您提供按年和月分组的结果