CakePHP:如何使paginator组件使用不同的计数?

时间:2014-08-04 06:04:07

标签: cakephp pagination

我使用此代码进行简单的分页:

$paginate = array(
    'limit' => 30,
    'fields' => array('DISTINCT Doctor.id','Doctor.*'),
    'order' => array('Doctor.id' => 'desc'),
    'joins' => array(
        array('table' => 'doctors_medical_degrees',
            'alias' => 'DoctorsMedicalDegree',
            'type' => 'INNER',
            'conditions' => array(
                'Doctor.id = DoctorsMedicalDegree.doctor_id',
            )
        ),
    ),
    'recursive' => -1,
);
$this->Paginator->settings = $paginate;
$data = $this->Paginator->paginate('Doctor');

现在的问题是我正在使用Inner join所以对于Distinct结果我正在使用Distinct Doctor.id,但是在查询分页时的cakephp计数查询不包括Distinct Doctor.id

'query' => 'SELECT COUNT(*) AS `count` FROM `pharma`.`doctors` AS `Doctor` INNER JOIN `pharma`.`doctors_medical_degrees` AS `DoctorsMedicalDegree` ON (`Doctor`.`id` = `DoctorsMedicalDegree`.`doctor_id`)'

你可以看到否

  

COUNT(DISTINCT Doctor.id)

所以分页会返回更多可以实际返回的结果

2 个答案:

答案 0 :(得分:2)

问题在于,分页符没有将字段传递给find('count')调用,因此默认情况下它始终依赖于*

但即使它会传递字段,传递一个数组会使find('count')调用期望将要计数的字段作为COUNT()表达式传递,即类似

'fields' => array('COUNT(DISTINCT Doctor.id) as `count`')

然而,无论如何这对于paginator都无效,所以您需要的是自定义find('count')来电。

自定义查询分拣

有关详细信息,请参阅 Cookbook > Pagination > Custom Query Pagination

自定义查询分页可能是您最好的选择,这完全取决于您如何进行计数。

例如,你可以使用paginator组件传递的额外值,这样你就可以传递字段来指望find('count')`调用,就像这样(未经测试的示例代码):< / p>

class Doctor extends AppModel {
    // ...

    public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
        $parameters = compact('conditions');
        if($recursive != $this->recursive) {
            $parameters['recursive'] = $recursive;
        }

        if(!empty($extra['countField'])) {
            $parameters['fields'] = $extra['countField'];
            unset($extra['countField']);
        }

        return $this->find('count', array_merge($parameters, $extra));
    }
}
$this->Paginator->settings = array(
    'limit' => 30,
    'fields' => array('DISTINCT Doctor.id','Doctor.*'),
    // ...
    'countField' => 'DISTINCT Doctor.id'
);
$data = $this->Paginator->paginate('Doctor');

然后应该创建一个看起来像

COUNT查询
SELECT COUNT(DISTINCT Doctor.id) AS `count` ...

答案 1 :(得分:0)

我在CakePHP - Pagination total count differs from actual count when using DISTINCT找到了解决方案 在模型中添加公共函数paginateCount,并在分页器中使用distinct选项,如:

$this->paginate = array('limit' => $limit, 'order' => array('Item.created' => 'ASC', 'Item.code' => 'ASC'),
            'fields' => 'DISTINCT Item.*',
            'conditions' => $conditions,
            'countField'   => array('Item.id'),
            'joins' => $joins,
            'distinct' => 'Item.id',
            'contain' => array(
                'Image' => array('limit' => 1),
                'ItemsTag'
                )
            );