Как я могу написать этот sql-запрос, следуя способу Magento?


Как я могу написать этот небезопасный, уродливый запрос, следуя пути Magento, без использования коллекции?

select (select sum(points) FROM ".$this->getTable('mymodule/registry')." where points < 0 and entity_id=".$customerId.") as points_spent,
(select sum(points) FROM ".$this->getTable('mymodule/registry')." where points > 0  and entity_id=".$customerId.") as points_received,
(select sum(points) FROM ".$this->getTable('mymodule/registry')."  where entity_id=".$customerId.") as points_current

РЕДАКТИРОВАТЬ

Возможное решение.

В модели ресурсов я могу поместить что-то вроде этого:

$adapter = $this->_getReadAdapter();

        $receivedPoints = $adapter->select()
            ->from(array('mymodule/registry'), array(new Zend_Db_Expr('sum(points)')))
            ->where('points > ?', 0)
            ->where('entity_id = ?', $customerId);

        $spentPoints = $adapter->select()
            ->from(array('mymodule/registry'), array(new Zend_Db_Expr('sum(points)')))
            ->where('points < ?', 0)
            ->where('entity_id = ?', $customerId);

        $query = $adapter->select()
            ->from(
                array('mymodule/registry'),
                array('current_points'  => new Zend_Db_Expr('sum(points)'),
                      'received_points' => new Zend_Db_Expr('(' . $receivedPoints . ')'),
                      'spent_points'    => new Zend_Db_Expr('(' . $spentPoints . ')')
                )
            )
            ->where('entity_id = ?', $customerId);
        return $adapter->fetchRow($query);
Author: Valerio Masciotta, 2013-10-09

2 answers

Попробуйте добавить эту функцию в свой класс коллекции. Моя логика заключается в том, что у вас есть сумма баллов, сгруппированных ниже 0 и выше 0, и все они.

class My_Module_Model_Mysql4_Registry_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
    public function _construct()
    {
        $this->_init('mymodule/registry');
    }

    public function getSumOfPoints($customerId)
    {
        $this->addFieldToFilter('customer_id', $customerId);

        $this->getSelect()
            ->reset('columns')
            ->columns(new Zend_Db_Expr("sign(points) as sign"))
            ->columns(new Zend_Db_Expr("sum(points) as summ"))
            ->group(new Zend_Db_Expr("sign(points)"));
        return $this;
    }
}

И вы можете получить результаты, вызвав эту функцию в любом месте:

$results = Mage::getResourceModel('mymodule/registry_collection')->getSumOfPoints($customerId);
foreach ($results as $result) {
    print_r($result->getData());
}

Если вы правильно изложите все вышесказанное, это даст следующий результат:

Array
(
    [sign] => -1 //summ of points less than 0
    [summ] => -166
)
Array
(
    [sign] => 1 //summ of points great than 0
    [summ] => 312
)

Вы можете получить сумму всех баллов, добавив два результата выше. Если вы не хотите использовать класс коллекции, вы можете применить эту логику к своему собственному коду, использующему ресурс модель. Класс коллекции генерирует sql-запрос, приведенный ниже, попробуйте сначала этот запрос, если он дает соответствующий результат, вы можете использовать код, приведенный выше:

SELECT
    sign(points)AS sign,
    sum(points)AS summ
FROM
    `mymodule_registry` AS `main_table` //put here real table name
WHERE
    (customer_id = '4') //put real customer id
GROUP BY
    sign(points)
 3
Author: mageUz, 2013-10-10 14:15:40

В конце концов, эта часть Magento полагается на Zend_Db, так что вы ищете: Zend_Db_Select. lib/Varien (и в более новой версии Magento lib/Magento) расширяет эту часть.

Объектом, используемым для выбора, является varien_db_select, который расширяет Zend_Db_Select

 $db = Mage::getSingleton('core/resource')->getConnection('core_read');//(Magento|Varien)_Db_Adapter_Pdo_Mysql
    $db->select();
    //does:
    public function select()
    {
        return new Varien_Db_Select($this);
    }
 3
Author: FlorinelChis, 2013-10-09 17:12:22