CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式
Posted
技术标签:
【中文标题】CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式【英文标题】:CakePHP 2.2.4 cannot paginate results using HAVING clause and calculated field - Haversine formula 【发布时间】:2013-02-12 12:06:21 【问题描述】:在使用 Cakephp 2.2.4 中的半正弦公式计算距离时,我试图对结果列表进行分页,但在 having 子句中的计算字段周围出现错误。
我已经认真地花费了数周时间试图弄清楚这一点,但我做不到。我已经阅读了几篇文章,有些说我需要重写 count 方法,有些说尝试其他但与旧版 Cake 相关的东西。
有人可以确切地告诉我我需要做什么才能使其正常工作吗?肯定有数百人试图实现同样的目标并取得了成功!
我使用的代码是:
'Business' => array(
'conditions' => array(
'Business.is_active' => 1
),
'fields' => array(
'Business.*',
'( 6371 * acos( cos( radians(' . $location['Location']['latitude'] . ') ) * cos( radians( Business.latitude ) ) * cos( radians( Business.longitude ) - radians(' . $location['Location']['longitude'] . ') ) + sin( radians(' . $location['Location']['latitude'] . ') ) * sin( radians( Business.latitude ) ) ) ) AS distance'
),
'group' => array(
'Business.id HAVING distance <= 5',
),
'contain' => array(
'UserReview',
'Certification',
'Package' => array(
'MassageType',
'PackageVariation' => array(
'order' => array(
'cost_in_dollars' => 'ASC'
)
)
)
),
'order' => array(
'distance' => 'ASC',
'Business.name' => 'ASC',
)
)
我不断收到的错误是:
错误:SQLSTATE[42S22]:未找到列:1054 'have clause' 中的未知列 'distance'
请帮忙!
【问题讨论】:
为什么不在这里使用虚拟字段? 你最好在mysql中使用存储过程和存储函数 【参考方案1】:在尝试找到解决这个有子句问题的解决方案后,我也放弃了。似乎在 CakePHP V2 中是不可能的。最后我不得不换一种方式:
$expression = '( 3959 * acos( cos( radians(' . $session_lat . ') ) * cos( radians( User.lat ) ) * cos( radians( User.lng ) - radians(' . $session_lng . ') ) + sin( radians(' . $session_lat . ') ) * sin( radians( User.lat ) ) ) )';
$conditions[] = $expression . ' < 100';
$this->controller->Paginator->settings = array(
'fields' => array('Item.*', $expression.' as distance'),
'limit' => $limit,
'order' => array('Item.id' => 'Desc'),
'conditions' => $conditions,
'joins' => $joins,
'paramType' => 'querystring'
);
所以,如您所见,我已将计算字段再次置于 where 条件下。我希望它会对某人有所帮助。
【讨论】:
【参考方案2】:这种情况的解决方案是使用虚拟字段:
$this->Business->virtualFields = array(
'distance' => '( 6371 * acos( cos( radians(' . $location['Location']['latitude'] . ') ) * cos( radians( Business.latitude ) ) * cos( radians( Business.longitude ) - radians(' . $location['Location']['longitude'] . ') ) + sin( radians(' . $location['Location']['latitude'] . ') ) * sin( radians( Business.latitude ) ) ) )'
);
之后,您可以使用“距离”作为字段:
$this->Paginator->settings = array(
'limit' => 20,
'order' => array('Business.distance' => 'ASC'),
'conditions' => array('Business.distance <=' => 100)
);
$data = $this->Paginator->paginate('Business');
您可以在此处阅读有关 CakePHP 虚拟字段的更多信息:http://book.cakephp.org/2.0/en/models/virtual-fields.html
【讨论】:
以上是关于CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式的主要内容,如果未能解决你的问题,请参考以下文章
由于缺少 PHP 扩展,CakePHP 3 无法连接到数据库
无法使用 cakePHP requestAction 加载完整视图