我创建了一个这样的洋红色集合来计算与LAT长的距离。

$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
            $collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
            ->having('distance <10')
            ->order('distance ' . Varien_Db_Select::SQL_ASC);

但是我会发现错误SQLSTATE [42S22]:找不到列:1054未知列“距离”中的“ avate oble”。

当我打印收集对象距离时,计算正确。那是什么问题?

我的问题类似于这个问题 在Magento Collection中使用“ Have”的问题

我正在使用分页收集,如果我删除了分页课,那么它可以很好地完成。但是我无法用提供的解决方案解决。这是我的分页代码。

_prepareLayout() 我把这个功能

$pager = $this->getLayout()->createBlock('page/html_pager', 'pager');
          $pager->setAvailableLimit(array(5=>5,10=>10,20=>20,'all'=>'all'));
          $pager->setCollection($this->getCollection());
          $this->setChild('pager', $pager);
          $this->getCollection()->load();
          return $this;

还将此功能添加到块文件中

  public function getPagerHtml()
  {
    return $this->getChildHtml('pager');
  }

并在phtml文件中称此为 <?php echo $this->getPagerHtml(); ?>

有帮助吗?

解决方案

我可以尝试使用 addExpressionFieldToSelect.
您可以在 Mage_Core_Model_Resource_Db_Collection_Abstract.
就您而言,应该是这样的:(这只是一个假设,您可能会遇到一些错误,但是这个想法还可以)

$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
$collection->addExpressionFieldToSelect('distance', '( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( {{latitude}}) ) * cos( radians( {{longitude}}) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( {{latitude}}) ) ) )', array('latitude'=>'latitude', 'longitude'=>'longitude'));
$collection->getSelect()->having('distance > 10');

addExpressionFieldToSelect 这样的工作:
第一个参数是表达式的别名(虚拟字段名称)。
第二个参数是表达式。用占位符包裹的arround替换字段名称 {{...}}
第三个参数是占位符信函(没有 {{}})。就你而言 latitide 占位符对应 latitude 字段如此 {{latitude}} 将被取代 latitude. 。也是如此 longitude.

编辑
在添加分页时存在问题 $collection 像这样

$collection->setCurPage(1)->setPageSize(5);  

这是问题的回溯。加载集合时称为 _renderLimit(). 。该方法看起来像这样

protected function _renderLimit()
{
    if($this->_pageSize){
        $this->_select->limitPage($this->getCurPage(), $this->_pageSize);
    }

    return $this;
}

所以这要打电话 getCurPage() (看 Varien_Data_Collection 班级)。
getCurPage 还有一个额外的验证来查看页码是否不超出最大范围,因此它计算出页面的总数 getLastPageNumber().
这里的问题是,Magento重置SELECT中的列以计算收集大小。在 Varien_Data_Collection_Db::getSelectCountSql 有这样的:

$countSelect->reset(Zend_Db_Select::COLUMNS);

通过重置列最终使用此SQL

SELECT COUNT(*) FROM `table_name_here` AS `main_table` HAVING (distance < 10)

这就是生成错误的原因。

我在这里看到2个选项。

  1. 您覆盖了收集课程的方法 getSelectCountSql并删除列重置:

    public function getSelectCountSql()
    {
        $this->_renderFilters();
    
        $countSelect = clone $this->getSelect();
        $countSelect->reset(Zend_Db_Select::ORDER);
        $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
        $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
        //$countSelect->reset(Zend_Db_Select::COLUMNS);//comment this line
    
        $countSelect->columns('COUNT(*)');
    
        return $countSelect;
    }
    
  2. 你覆盖了 getCurPage() 跳过范围验证的方法:

    public function getCurPage($displacement = 0){
        if (!empty($this->_curPage)){
            return $this->_curPage + $displacement;
        }
        return 1;
    }
    

编辑到编辑
为了避免影响其余模块,您可以覆盖 getCurPage 这样的方法:

public function getCurPage($displacement = 0){
    if (!$this->getDirectCurPage()){//if a specific flag is not set behave as default
        return parent::getCurPage($displacement);
    }
    if (!empty($this->_curPage)){
        return $this->_curPage + $displacement;
    }
    return 1;
}

现在,当您想使用您的 having 方法只需将其添加到您的集合中

$collection->setDirectCurPage(1);

其他提示

尝试使用此方法:

$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
            $collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
            ->addAttributeHaving('distance <10')
            ->addAttributeToSort('distance', Varien_Db_Select::SQL_ASC);

你可以尝试 where() 代替 having() 因为您不使用任何 JOIN 语句:

$collection->getSelect()->where('distance > ?', 10);
许可以下: CC-BY-SA归因
scroll top