2010-02-18 4 views
1

나는 경기 결과의 리그 테이블을 표시하는 zend app가 있습니다. 기본 프로세스는 포함될 이벤트 목록을 결정한 다음 SQL 쿼리에 동적으로 열 집합을 추가하는 것입니다. 내 초기 구현은 오히려 쓰레기이며 그것을 refector 싶습니다. 필자는 수동으로 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

사실 SQL이 아니기 때문에 select 인스턴스 $ sql을 호출하는 것을 좋아하지 않습니다. 나는 그것을 $ select라고 부른다. 왜냐하면 그것이 무엇인지 알기 때문이다. – Layke

답변

2

의 I 내가 동적으로 내 쿼리에 추가 필드를 추가하려면 '열() 메소드를 사용하고, 올바르게 열의 특정 값을 포맷 할 Zend_Db_Expr를 사용할 수 있다는 것을 알아 냈 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

퍼펙 .

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