如何比较收藏中Magento的两个不同字段


How do I compare 2 different fields in Magento in a collection

我正试图将Magento系列中的产品价格与其销售价格进行比较。具体来说,试图找到销售价格大于或等于其基本价格的所有产品。

从逻辑上讲,我试图将字段名称放入addAttributeToFilter调用:

->addAttributeToFilter('special_price', array('gteq' => 'special_price'));

但这并没有奏效。有没有一种好的方法可以做到这一点,而不需要我获取每个有销售价格的产品来手动检查销售价格是否大于或等于其基本价格?

解决方案

这是相当奇怪的,显示出Magento收藏有时是多么奇怪。事实证明,仅仅因为你把->addAttributeToSelect('price')放进了你的呼叫链,并不意味着你能以一种巧妙的方式获得价格。所以我要做的是放入一个条件,这样我就可以在查询的其他部分访问它。我选择了->addAttributeToFilter('price', array('gteq' => 0))。为了特价,我也不得不这么做。

然后,当涉及到放入where条件时,我仍然无法使用简单的名称访问价格和特价,所以我必须使用它们的表值,所以我的where语句最终是$products->getSelect()->where('_table_special_price.value >= _table_price.value');

最后,这就是我的整个链的样子(其中有一些自定义属性):

$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('id')
->addAttributeToSelect('name')
->addAttributeToSelect('price')
->addAttributeToSelect('special_price')
->addAttributeToFilter('price', array('gteq' => 0))
->addAttributeToFilter('special_price', array('gteq' => 0))
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('discontinued', array('neq' => 1))
->addAttributeToFilter('status', 1)
;

$products->getSelect()->where('_table_special_price.value>=_table_price.value');

试试这个:

->addAttributeToFilter('special_price', array ('gteq' => new Zend_Db_Expr('price') ) );

如果它不起作用,你可以选择这个:

->getSelect()->where("special_price >= price");

不得不做类似的事情。

除了获取special_price>=价格的产品外,它还演示了一种查询计算字段的策略(排除价格以.09或.05结尾的产品)

此外,它还演示了如何在(大)集合中分页,从而最大限度地减少内存使用等。这可能对您有用。

$products = Mage::getModel('catalog/product')
        ->getCollection()
        ->addAttributeToSelect('*')
        ->addAttributeToFilter('status', 1)
        ->addAttributeToFilter('price', array('neq' => '-1')) // Easy way to join price EAV tables to select
        ->addAttributeToFilter('special_price', array('neq' => '-1')); 
$price = 'at_price.value';
$special_price = 'at_special_price.value';
$price_cents = new Zend_Db_Expr("({$price} - FLOOR({$price})) * 100");
$special_price_cents = new Zend_Db_Expr("({$special_price} - FLOOR({$special_price})) * 100");
$allProducts->getSelect()
    ->where("(
        {$price_cents} != 9 OR 
        {$special_price_cents} != 5
    ) AND 
    {$special_price_cents} >= {$price_cents}");
// You can see the query by uncommenting this part    
//echo "'r'n'r'n";
//echo $allProducts->getSelect();
//echo "'r'n'r'n";
$products->setPageSize(100);
$pages = $products->getLastPageNumber();
$currentPage = 1;
do {    
    $products->setCurPage($currentPage);
    $products->load();
    foreach ($products as $_product) {
        echo "Product: ID-" . $_product->getId() . ", price-" . $_product->getPrice() . ", special price-" . $_product->getSpecialPrice() . "'r'n";
        echo "Memory used: " . memory_get_usage() . " / " . memory_get_peak_usage() . "'r'n";
    }
    $currentPage++;
    //make the collection unload the data in memory so it will pick up the next page when load() is called.
    $allProducts->clear();
} while ($currentPage <= $pages);