2010-02-18 61 views
1

我有一個zend應用程序,顯示比賽結果的聯賽表。基本過程是確定要包含的事件列表,然後動態地將一組列添加到SQL查詢中。我最初的實施是相當垃圾的,我想反駁它。我手動建立一個SQL字符串,最後調用db-> fetch()。我知道 - 垃圾代碼,但我仍然在學習zend,並有一個截止日期。Zend DB和有條件的病例陳述

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); 
    } 

.... 

任何想法和建議?

+0

我不喜歡調用select實例$ sql,因爲它不是SQL。我把它稱爲$ select,因爲那就是它。 – Layke 2010-02-24 13:05:38

回答

2

的PERFECTO answerino

$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); 
1

我想通了,我可以用「列()」方法來額外的字段動態地添加到我的查詢,並使用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'));