寒碜的编码及改进

背景:

有一个讲座表(speech)、讲座分类表(theme_type)、教工表(teacher)、学院表(college)
需要计算出讲座表中 某个学院、所有分类、某年、所有月份的讲座数量。

我寒碜的写法:

public function detail($pk) {
        $pk=$pk?:I('pk');
        $y = I('year')?:date('Y',TIME);
        $page = I('page');
        switch (I('page')){
            case 'last':
                $y=--$y;
                break;
            case 'next':
                $y=++$y;
                break;
            default :
                $y = date('Y',TIME);
        }
        $coll_info = $this->where(array($this->getPk()=>$pk))->field('in_charge_id')->find(['hy'=>true]);
        $associate = array(
            'teacher|in_charge_id|user_id|department_id',
            'college|teacher.department_id|id|id AS coll_id,name AS college_name',
            'theme_type|theme_id|id|theme_name'
        );
        $theme_sum = M('theme_type')->where(array('status'=>array('lt',9)))->count();
        $th = M('theme_type')->where(array('status'=>array('lt',9)))->select();
        $theme = [];
        foreach($th as $v){
            $theme[$v['id']]=$v['theme_name'];
        }
        $sum = [];

// 看这里
        for($c = 1; $c <= $theme_sum; $c++){
          for($m = 1; $m<=12; $m++) {
            if($m < 10) {
              $m='0'.$m;
              $sum[$theme[$c]][]=$this->associate($associate)
                ->where(array('college.id'=>$coll_info['department_id'],'speech_time'=>array('LIKE',$y.'-'.$m.'%'),'theme_type.id'=>$c,'check_status'=>2,'status'=>array('lt',9)))
                ->count();
            }else {
              $m .='';
              $sum[$theme[$c]][]=$this->associate($associate)
                ->where(array('college.id'=>$coll_info['department_id'],'speech_time'=>array('LIKE',$y.'-'.$m.'%'),'theme_type.id'=>$c,'check_status'=>2,'status'=>array('lt',9)))
                ->count();
            }
          }
        }
// 这里为止

        $y >= date('Y',TIME) ? $next = false : $next = true;
        return array(
            'str' => array('year'=>$y,'pk'=>$pk,'noNext'=>$next),
            'json' => json_encode(array('theme'=>$theme,'sum'=>$sum),JSON_UNESCAPED_UNICODE)
        );
    }

想要这样的结果:

问题:

1、这样效率太低了!数据量一大就die掉了!数据操作不要写在循环里!
2、if else也好寒碜!可以用三元运算符嘛!高级点可以用sprintf('%2d',$m)
3、分类的id:$c怎么从1开始?如果数据库中某一个分类删除了咋办!

改进:

public function detail($pk) {
        $pk=$pk?:I('pk');
        $y = I('year')?:date('Y',TIME);
        switch (I('page')){
            case 'last':
                $y=--$y;
                break;
            case 'next':
                $y=++$y;
                break;
            default :
                $y = date('Y',TIME);
        }
        $coll_info = $this->where(array($this->getPk()=>$pk))->field('in_charge_id')->find(['hy'=>true]);
// 改进-自己写sql
        $result = $this->query("SELECT SUBSTRING(speech.speech_time, 6, 2) AS `speech_month`,speech_time, speech.theme_id, theme.theme_name,COUNT(speech.id) AS `speech_count` FROM `zsjy_speech` AS `speech` INNER JOIN `zsjy_teacher` AS `teacher` ON speech.in_charge_id = teacher.user_id  INNER JOIN `zsjy_theme_type` AS `theme` ON speech.theme_id = theme.id  INNER JOIN `zsjy_college` AS `college` ON teacher.department_id = college.id WHERE college.id = ". $coll_info['department_id'] ." AND speech.speech_time LIKE '". $y ."%'  GROUP BY speech_month, theme.id");
// 至此 整理出所需数据
        $th = M('theme_type')->where(array('status'=>array('lt',9)))->select();
        $theme = array();
        $sum = array();
        foreach($th as $v){
            $theme[$v['id']]=$v['theme_name'];
            for($i = 1; $i<=12; $i++) {
                $sum[$v['theme_name']][$i] = 0;
                foreach($result as $vv){
                    if($vv['theme_name'] == $v['theme_name'] && $vv['speech_month'] == $i) {
                      $sum[$v['theme_name']][$i] = $vv['speech_count'] - 0;
                    }
                }
            }
        }
        $y >= date('Y',TIME) ? $next = false : $next = true;
        return array(
            'str' => array('year'=>$y,'pk'=>$pk,'noNext'=>$next),
            'json' => json_encode(array('theme'=>$theme,'sum'=>$sum))
        );
    }

当sql比较复杂的时候就直接用 Model->query(sql)效率更高点!代码也少点,取出来再在外面整理成想要的格式!

原文地址:https://www.cnblogs.com/sameen/p/5324092.html