Вопрос

Я создал одну коллекцию Magento, подобную этой, чтобы рассчитать расстояние от LAT Long.

$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 Неизвестный столбец «расстояние» в «имеющемся предложении».

Когда я печатаю расчет расстояния объекта коллекции. так в чем была проблема?

Моя проблема похожа, как этот вопрос Проблема с использованием «иметь» в коллекции Magento

Я использую лицензию на коллекции, если я удаляю класс страниц, то она работает идеально. Но я не могу решить с предоставленным решением. Вот мой код страгивания.

В _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 работает так:
Первый параметр - псевдоним выражения (имя виртуального поля).
Второй параметр - это выражение. Замените имена поля на заполнители, обернутые {{...}}
Третий параметр - это соответствие заполнителя (без {{}}) В твоем случае 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 сбрасывает столбцы в выборе для расчета размера сбора. В 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 с атрибуция
Не связан с magento.stackexchange
scroll top