Zend DB и условные операторы case

У меня есть приложение zend, которое отображает таблицу результатов гонок. Основной процесс состоит в том, чтобы определить список включаемых событий, а затем динамически добавить набор столбцов в запрос SQL. Моя первоначальная реализация довольно вздорна, и я хочу ее отрефектировать. Я вручную создаю строку SQL и в самом конце вызываю db-> fetch (). Я знаю - дерьмовый код, но я все еще изучал зенд, и у меня был крайний срок.

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.

Условный столбец для запроса на основе других столбцов в 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);
    }

....

Есть идеи / предложения?


person emeraldjava    schedule 18.02.2010    source источник
comment
Мне тоже не нравится называть экземпляр select $ sql, поскольку на самом деле это не SQL. Я называю это $ select, потому что так оно и есть.   -  person Layke    schedule 24.02.2010


Ответы (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);
person Layke    schedule 24.02.2010

Я понял, что могу использовать метод 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'));
person emeraldjava    schedule 05.03.2010