Получение SUM (значение) из связанной таблицы - PullRequest
0 голосов
/ 23 ноября 2011

У меня есть таблица базы данных, скажем, Person, и каждый человек имеет голоса, сохраненные в таблице голосования.

У каждого человека будет много голосов, и некоторые из них уже подняты, а некоторые - нет, поэтому меня не интересует COUNT.

У меня есть следующий запрос для получения голосов за одного человека:

$votes = $this->Vote->query("
  SELECT IFNULL( SUM( value ) , 0 ) AS vote_count
  FROM `votes`
  WHERE person_id = {$person_id}"); 

Могу ли я получать эту информацию для Лица каждый раз, когда я звоню

$this->person->find("all")

1 Ответ

0 голосов
/ 23 ноября 2011

Это можно сделать с помощью $ virtualFields :

В модель голосования добавляю следующее виртуальное поле:

var $virtualFields = array(
    'vote_count' => 'IFNULL( SUM( Vote.value ) , 0 )'
);

В модели Person я получаю это каждый раз, используя следующие отношения $ hasMany:

var $hasMany = array('Vote' => array('fields' => array('vote_count')));

Обратите внимание, что по умолчанию он всегда будет извлекать каждое поле в таблице голосования, это приведет к извлечению поля SUM 'voice_count' по умолчанию и покажет только одну строку, как и ожидалось, если вы выписали запрос полностью.

Если вы хотите получить все строки и удалить виртуальное поле SUM, вам нужно указать все поля (при необходимости) в массиве полей, кроме поля 'привели к подсчету', например,

var $hasMany = array('Vote' => array('fields' => array('id', 'value')));

Я бы предположил, что это лучше контролировать, если в модели Person есть пара функций, которые позволят вам на лету решить, как вы хотите получить голоса:

function allWithVoteCounts() {
    $this->bindModel(array('hasMany' => 
        array('Vote' => array(
            'fields' => array('vote_count')
            )
        )
    ));
    return $this->find('all');
}

function allVotes() {
    $this->bindModel(array('hasMany' => 
        array('Vote' => array(
            'fields' => array('id', 'user_id', 'person_id', 'value', 'date')
            )
        )
    ));
    return $this->find('all');
}

Тогда в контроллере вы можете позвонить:

$persons = $this->Person->allVotes();

или

$persons = $this->Person->allWithVoteCounts();
...