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 2.0 无法保存

无法使用 cakePHP requestAction 加载完整视图

无法在本地环境中使用 docker 连接到 cakephp 中的 mysql 数据库

cakephp 在 Ubuntu 上无法进行 url 重写

CakePHP 应用程序无法在 localhost 中启动