Frage

Ich habe eine Magento-Sammlung wie diese erstellt, um die Entfernung von Lat Long zu berechnen.

$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);

Aber ich erhalte die Fehlermeldung SQLSTATE[42S22]:Spalte nicht gefunden:1054 Unbekannte Spalte „Distanz“ in „Having-Klausel“.

Wenn ich das Sammlungsobjekt ausdrucke, stimmt die Entfernungsberechnung.Also, was war das Problem?

Mein Problem ist ähnlich wie diese Frage Problem bei der Verwendung von „have“ in der Magento-Sammlung

Ich verwende die Paginierung für die Sammlung. Wenn ich die Paginierungsklasse entferne, funktioniert es perfekt.Aber ich kann das Problem mit der bereitgestellten Lösung nicht lösen.Hier ist mein Paginierungscode.

In _prepareLayout() Funktion Ich habe das gesetzt

$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;

Fügen Sie diese Funktion auch in der Blockdatei hinzu

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

und nennen Sie dies in der HTML-Datei als <?php echo $this->getPagerHtml(); ?>

War es hilfreich?

Lösung

Ich kann versuchen, es zu verwenden addExpressionFieldToSelect.
Die Methode finden Sie in Mage_Core_Model_Resource_Db_Collection_Abstract.
In Ihrem Fall sollte es ungefähr so ​​aussehen:(Dies ist nur eine Annahme, es könnten einige Fehler auftreten, aber die Idee ist in Ordnung)

$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');

Der addExpressionFieldToSelect funktioniert so:
Der erste Parameter ist der Alias ​​des Ausdrucks (Name des virtuellen Felds).
Der zweite Parameter ist der Ausdruck.Ersetzen Sie die Feldnamen durch umschlossene Platzhalter {{...}}
Der dritte Parameter ist die Platzhalterkorrespondenz (ohne). {{}}).In Ihrem Fall latitide Platzhalter entspricht latitude Feld also {{latitude}} wird durch ersetzt latitude.Das Gleiche gilt für longitude.

[BEARBEITEN]
Es gibt ein Problem beim Hinzufügen einer Paginierung zum $collection so was

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

Hier ist die Rückverfolgung des Problems.Wenn die Sammlung geladen wird, wird dies aufgerufen _renderLimit().Die Methode sieht so aus

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

    return $this;
}

Das ruft also getCurPage() (sehen Varien_Data_Collection Klasse).
getCurPage verfügt über eine zusätzliche Überprüfung, um festzustellen, ob die Seitenzahl nicht außerhalb des maximalen Bereichs liegt, und berechnet so die Gesamtzahl der Seiten darin getLastPageNumber().
Das Problem hierbei ist, dass Magento die Spalten in der Auswahl zur Berechnung der Sammlungsgröße zurücksetzt.In Varien_Data_Collection_Db::getSelectCountSql da ist das:

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

Durch Zurücksetzen der Spalten erhalten Sie diese SQL

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

Dies ist es, was den Fehler erzeugt.

Ich sehe hier 2 Möglichkeiten.

  1. Sie überschreiben in Ihrer Sammlungsklasse die Methode getSelectCountSqlund entfernen Sie die Spalte zurückgesetzt:

    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. Sie überschreiben die getCurPage() Methode zum Überspringen der Bereichsvalidierung:

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

[BEARBEITEN ZUM BEARBEITEN]
Um zu vermeiden, dass sich dies auf die übrigen Module auswirkt, können Sie das überschreiben getCurPage Methode wie diese:

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;
}

Nun, wenn Sie Ihre verwenden möchten having Methode fügen Sie dies einfach Ihrer Sammlung hinzu

$collection->setDirectCurPage(1);

Andere Tipps

Versuchen Sie es stattdessen:

$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);

Du könntest es versuchen where() Anstatt von having() Wie Sie keine verwenden JOIN Aussagen:

$collection->getSelect()->where('distance > ?', 10);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top