代码之家  ›  专栏  ›  技术社区  ›  emeraldjava

Zend DB和条件case语句

  •  1
  • emeraldjava  · 技术社区  · 16 年前

    我有一个Zend应用程序,显示比赛结果的排名表。基本过程是确定要包含的事件列表,然后动态地向SQL查询添加一组列。我的初始实现是相当垃圾的,我想重新定义它。我手动构建了一个SQL字符串,并在最后调用db->fetch()。我知道-废话代码,但我仍然在学习Zend并且有一个最后期限。

    public function league()
    {
        ...
    
        $SQL = 'SELECT rr.runner AS runnerid, ru.firstname as firstname, ru.surname as surname, ';
    
        // get the list of events        
        foreach($events as $eventrow)
        {
            $eventTable = new Model_DbTable_Event();
            $event = $eventTable->find($eventrow->event)->current();
            // generate the conditional column
            $sum = $this->getEventSQL($event,$division->gender);
            // append to the SQL string (nasty) 
            $SQL = $SQL . $sum;
        }
    
        $SQL = $SQL . 'lrd.racesComplete, lrd.pointsTotal, c.name as company ';
        $SQL = $SQL . 'FROM raceresult rr ';
        $SQL = $SQL . 'JOIN runner ru ON rr.runner = ru.id ';
        $SQL = $SQL . 'LEFT JOIN company c ON c.id = ru.company ';
        $SQL = $SQL . 'JOIN race ra ON rr.race = ra.id ';
        ...
        ...
    
        $db = Zend_Db_Table::getDefaultAdapter();
        $this->view->leaguetable = $db->fetchAll($SQL);
    }
    
    // create the SUM sql statement for a specific event
    // SUM(CASE rr.race WHEN 15 THEN rr.points ELSE NULL END) as Result1,
    // SUM(CASE rr.race WHEN 16 THEN rr.points ELSE NULL END) as Result2,
    function getEventSQL($event,$type)
    {
        $eventTable = new Model_DbTable_Event();
        $sum_sql = 'SUM(CASE rr.race ';
        foreach($races as $race)
        {
            $sum_sql = $sum_sql . sprintf('WHEN %d',$race->id) . ' THEN rr.points ';
        }   
        $sum_sql = $sum_sql . sprintf('ELSE NULL END) as \'%s\',',$event->id);
        return $sum_sql;
    }
    

    我知道我需要使用SQL select/case语句。

    Conditional column for query based on other columns in MySQL

    我想把这个逻辑转移到一个扩展zend-db-table-abstract的类中,但是我仍然不确定什么是有条件地控制所选列的最佳方法。我知道我可以添加多个where()子句,这个场景中可以使用column()方法吗?

    class Model_DbTable_League extends Zend_Db_Table_Abstract
    {
        protected $_name = 'leaguerunnerdata';
        protected $_primary = 'Id';
    
        public function leagueTable($min,$max)
        {
            $sql = $this->select()
                ->setIntegrityCheck(false)
                ->from(array('l'=>'league'),array('col','col2','col3'))
                ->where('l.league = ?',1)
                ->where('r.standard > ?',$min)
                ->where('r.standard < ?',$max)
                ->order('l.pointsTotal DESC');
            return $this->fetchAll($sql);
        }
    
    ....
    

    有什么想法/建议吗?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Layke    16 年前

    完美的安斯韦里诺

    $select = $this->select()->setIntegrityCheck(false)
    
    $select->from(array('l' => 'league'), array('leagueId'=> 'id', 'name','location','competitionName','eventManager','owner' )  )
                    ->join(array('r' => 'whateverRTableIs'),
                             'r.id = l.id',
                                 array())
                    ->where('l.league = ?',1)
                    ->where('r.standard > ?',$min)
                    ->where('r.standard < ?',$max)
                    ->order('l.pointsTotal DESC');
                return $this->fetchAll($select);
    
        2
  •  1
  •   emeraldjava    16 年前

    我发现我可以使用“columns()”方法动态地向查询中添加额外的字段,并使用zend_db_expr正确地格式化列的特定值。

    $select = $this->select()
    ->setIntegrityCheck(false)
    ->from(array('raceresult'=>'raceresult'),array())
    ->join(array('runner'=>'runner'),'runner.id=raceresult.runner',array('id','firstname','surname'));
        foreach($races as $taggedrace)
        {
            $select->columns(new Zend_Db_Expr(
                sprintf("SUM(CASE raceresult.race WHEN %d THEN raceresult.points ELSE NULL END) as %s",
                    $taggedrace->raceid,$taggedrace->tag)));
        }
    $select->join(array('race'=>'race'),'race.id = raceresult.race',array())
    ->join(array('event'=>'event'),'race.event = event.id',array())
    ->join(array('leagueevent'=>'leagueevent'),'leagueevent.event = event.id',array())
    ->join(array('leaguerunnerdata'=>'leaguerunnerdata'),
        'leaguerunnerdata.runner = raceresult.runner AND leaguerunnerdata.league=leagueevent.league',
        array('racesComplete','pointsTotal'))
    ->joinLeft(array('company'=>'company'), 'company.id = runner.company',array('name'))
    ->where( sprintf('leaguerunnerdata.standard BETWEEN %d AND %d ',$division->min,$division->max))
    ->where('runner.gender= ?',$division->gender)
    ->where('leagueevent.league = ?',$league)
    ->group(array('raceresult.runner','leaguerunnerdata.racesComplete','leaguerunnerdata.pointsTotal'))
    ->order(array('leaguerunnerdata.pointsTotal desc'));