Próbuję zbudować niestandardową kolekcję dla siatki w module administracyjnym Magento. Utworzyłem nową metodę kolekcji o nazwie „addAttributeHaving”, która wykonuje następujące czynności:
public function addAttributeHaving($value)
{
$this->getSelect()->having($value);
return $this;
}
Zobacz kod kolekcji:
$collection->addFieldToSelect(
array(
'entity_id',
'created_at',
'increment_id',
'customer_email',
'customer_firstname',
'customer_lastname',
'grand_total',
'status'
)
);
$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'), 'main_table.entity_id = sfop.parent_id', 'sfop.amount_authorized');
$collection->getSelect()->columns('sum(sfop.amount_authorized) AS AUTHD');
$collection->getSelect()->columns('grand_total - sum(sfop.amount_authorized) AS DIF_AU');
$collection->addFieldToFilter('main_table.state', array('in' => array('new','payment_review')));
$collection->addFieldToFilter('main_table.sd_order_type', array('neq' => 7));
$collection->addFieldToFilter('sfop.method', array('neq' => 'giftcard'));
$collection->addFieldToFilter('main_table.created_at', array('gt' => $this->getFilterDate()));
$collection->getSelect()->group(array('main_table.entity_id'));
$collection->addAttributeHaving('DIF_AU <> 0');
$collection->load(true,true);
$this->setCollection($collection);
Powoduje to wygenerowanie następującego kodu SQL, który działa idealnie dobrze i daje oczekiwane wyniki, gdy jest uruchamiany poza Magento.
[METHOD=Varien_Data_Collection_Db->printLogQuery] SELECT `main_table`.`entity_id`, `main_table`.`entity_id`, `main_table`.`created_at`, `main_table`.`increment_id`, `main_table`.`customer_email`, `main_table`.`customer_firstname`, `main_table`.`customer_lastname`, `main_table`.`grand_total`, `main_table`.`status`, `sfop`.`amount_authorized`, sum(sfop.amount_authorized) AS `AUTHD`, grand_total - sum(sfop.amount_authorized) AS `DIF_AU` FROM `sales_flat_order` AS `main_table` LEFT JOIN `sales_flat_order_payment` AS `sfop` ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('new', 'payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY `main_table`.`entity_id` HAVING (DIF_AU <> 0)
Jednak gdy próbuję załadować siatkę do Magento, pojawia się następujący błąd:
SQLSTATE [42S22]: Nie znaleziono kolumny: 1054 Nieznana kolumna „DIF_AU” w „z klauzulą”
Dodatkowo, jeśli usunę klauzulę have (która psuje moje wyniki), będę mógł użyć kolumny DIF_AU jako źródła danych w siatce.
źródło
sd_order_type
pochodzi?Odpowiedzi:
Odpowiem na własne pytanie tutaj. Wiem, tandetny, ale natknąłem się na odpowiedź, gdy przyjrzałem się bliżej faktycznemu śladowi stosu. Kolekcja ładuje się dobrze, jednak błąd pojawia się nieco później, gdy próbujemy uzyskać liczbę kolekcji w Varien_Data_Collection_Db :: getSelectCountSql () . Wytworzony z tego kod SQL to:
SELECT COUNT(*) FROM sales_flat_order AS main_table LEFT JOIN sales_flat_order_payment AS sfop ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY main_table.entity_id HAVING (DIF_AU <> 0)
Zauważysz, że instrukcja HAVING jest załączona, ale nie mamy już definicji kolumny DIF_AU. Wygląda na to, że będę musiał rozszerzyć niestandardową metodę getSelectCountSql () w mojej klasie kolekcji, aby uzyskać odpowiednią liczbę rekordów.
Utworzyłem rozszerzoną metodę getSelectCountSql () w niestandardowej klasie kolekcji, która dodaje z powrotem w brakującej kolumnie wymaganej dla instrukcji have.
źródło
count(distinct main_table.entity_id)
zamiastcount(*)
Przede wszystkim
$countSelect->reset(Zend_Db_Select::HAVING);
oznacza, że zresetuje sięHAVING
z twojej kolekcji. Oznacza to, że usunie klauzulę posiadania. I to nie jest to, czego chcesz. Możesz dodać go do kolekcji (app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()
tutaj.)Ale głównym winowajcą jest
getSize()
metoda, która istnieje wlib/Varien/Data/Collection/Db.php
pliku.Teraz zrobiłem poniżej.
Sprawdź, że nawet nie używam
getSelectCountSql()
. Właśnie czytam całe zapytanie SQL i pobieram wszystkie dane i zwracam ich liczbę . To wszystko.źródło
Naprawiłem ten problem tutaj: app / code / core / Mage / Catalog / Model / Resource / Product / Collection.php: 943 dodaj to: $ select-> reset (Zend_Db_Select :: HAVING);
Wystarczy skopiować aplikację / code / core / Mage / Catalog / Model / Resource / Product / Collection.php do app / code / local / Mage / Catalog / Model / Resource / Product / Collection.php
Mój kod wygląda teraz tak:
źródło
Podzapytanie: podzapytanie tabeli umożliwia zduplikowanie nazw kolumn
źródło
To działa
funkcja publiczna getSize () {if (is_null ($ this -> _ totalRecords)) {// $ sql = $ this-> getSelectCountSql (); $ sql = $ this-> getSelect (); $ this -> _ totalRecords = count ($ this-> getConnection () -> fetchAll ($ sql, $ this -> _ bindParams)); } return intval ($ this -> _ totalRecords); }
źródło