Estou tentando criar uma coleção personalizada para uma grade no módulo de administração do Magento. Eu criei um novo método de coleção chamado "addAttributeHaving", que faz o seguinte:
public function addAttributeHaving($value)
{
$this->getSelect()->having($value);
return $this;
}
Veja o código da coleção:
$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);
Isso produz o seguinte SQL, que executa perfeitamente bem e produz os resultados esperados quando executado fora do 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)
No entanto, quando tento carregar a grade dentro do Magento, recebo o seguinte erro:
SQLSTATE [42S22]: Coluna não encontrada: 1054 Coluna desconhecida 'DIF_AU' na 'cláusula having'
Além disso, se eu remover a cláusula having (que quebra meus resultados), posso usar a coluna DIF_AU para uma fonte de dados na Grade.
fonte
sd_order_type
vem?Respostas:
Na verdade, vou responder minha própria pergunta aqui. Eu sei, brega, mas me deparei com a resposta ao olhar muito mais de perto o rastreamento real da pilha. A coleção está carregando bem, no entanto, a falha ocorre um pouco mais tarde na execução, quando tentamos obter a contagem da coleção em Varien_Data_Collection_Db :: getSelectCountSql () . O SQL produzido a partir disso é:
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)
Você notará que a instrução HAVING está anexada, mas não temos mais nenhuma definição para a coluna DIF_AU. Parece que vou precisar estender um getSelectCountSql () personalizado na minha classe de coleção para obter a contagem de registros correta.
Criei um getSelectCountSql () estendido na classe de coleção personalizada que é adicionada novamente na coluna ausente necessária para a instrução having.
fonte
count(distinct main_table.entity_id)
em vez decount(*)
Antes de tudo
$countSelect->reset(Zend_Db_Select::HAVING);
, ele será redefinidoHAVING
da sua coleção. Isso significa que ele removerá a cláusula having. E não é o que você quer. Você pode adicioná-lo à coleção (app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()
aqui.)Mas o principal culpado é o
getSize()
método que existe nolib/Varien/Data/Collection/Db.php
arquivo.Agora eu fiz o abaixo.
Verifique se eu não estou nem usando o
getSelectCountSql()
. Estou apenas lendo todo o SQL QUERY e buscando todos os dados e retornando a contagem . Isso é tudo.fonte
Corrigi esse problema aqui: app / code / core / Mage / Catalog / Model / Resource / Product / Collection.php: 943 adicione isso: $ select-> reset (Zend_Db_Select :: HAVING);
Basta copiar app / code / core / Mage / Catalog / Model / Resource / Product / Collection.php para app / code / local / Mage / Catalog / Model / Resource / Product / Collection.php
Meu código está agora assim:
fonte
Subconsulta: a subconsulta da tabela permite nomes de colunas duplicados
fonte
Isso está funcionando
função pública 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); }
fonte