【问题标题】:How do i sort magento products collection with ORDER BY FIELD我如何使用 ORDER BY FIELD 对 magento 产品集合进行排序
【发布时间】:2013-01-20 10:39:10
【问题描述】:

我有一个自定义产品属性,实际上包含三个可能的值 “Frühjahr/Sommer”、“Herbst/Winter”、“”(空)。

我想按预定义的顺序按此值对产品集合进行排序 例如“Frühjahr/Sommer”、“Herbst/Winter”、“”或 “Herbst/Winter”、“Frühjahr/Sommer”、“”

这是交替的。 空值应该总是在最后,但可能会有更多的值出现,所以它必须是一个固定的预定义顺序。

我需要执行以下 MySQL ORDER BY FIELD (saison, "Frühjahr/Sommer", "Herbst/Winter", "")

问题是我不知道如何在 Magento 中执行这个命令。 我知道“->setOrder”-方法,但我需要提交一个固定的顺序,而不是使用 DESC 或 ASC。

我在 stackoverflow 和 google 上搜索了很多,但到目前为止没有答案。

希望你能帮到我

谢谢

[编辑回应 magalter 的回答]

不幸的是它不起作用我之前尝试过:

$this->_collection->getSelect()->order(new Zend_Db_Expr("FIELD(season, 'Frühjahr/Sommer','Herbst/Winter','')"));

结果是“处理您的请求时出错。

$this->_collection->getSelect();

返回:

SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='124' INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0 ORDER BY FIELD(season, 'Frühjahr/Sommer','Herbst/Winter','')

我在 phpMyAdmin 中执行了这个 sql 语句,并收到以下错误消息“'order clause' 中的未知列 'season'”

如果我按“季节”DESC 排序

$this->_collection->setOrder('season', 'DESC');

它可以工作...并生成以下 sql 语句

SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, IF(season_option_value_t2.value_id IS NULL, season_option_value_t1.value, season_option_value_t2.value) AS `season` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='124' INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0 LEFT JOIN `catalog_product_entity_int` AS `season_t1` ON e.entity_id=season_t1.entity_id AND season_t1.attribute_id='180' AND season_t1.store_id=0 LEFT JOIN `catalog_product_entity_int` AS `season_t2` ON e.entity_id=season_t2.entity_id AND season_t2.attribute_id='180' AND season_t2.store_id='1' LEFT JOIN `eav_attribute_option_value` AS `season_option_value_t1` ON season_option_value_t1.option_id=IF(season_t2.value_id > 0, season_t2.value, season_t1.value) AND season_option_value_t1.store_id=0 LEFT JOIN `eav_attribute_option_value` AS `season_option_value_t2` ON season_option_value_t2.option_id=IF(season_t2.value_id > 0, season_t2.value, season_t1.value) AND season_option_value_t2.store_id=1 ORDER BY `season` DESC

但这是 DESC 的顺序,而不是我想要的预定义顺序,所以我不能使用它。

我需要的是上面带有

的 SQL 语句
ORDER BY FIELD(season, 'Frühjahr/Sommer','Herbst/Winter','')

改为

ORDER BY `season` DESC

另一个想法???

【问题讨论】:

  • 为什么你的 $this->_collection->getSelect();示例与 $this->_collection->setOrder('season', 'DESC'); 有很大不同; ?您需要将所有需要的字段连接到集合,然后制作 $this->_collection->getSelect();
  • 这是个好问题。我认为 Magento “setOrder”-Method 确保所有需要的字段都连接起来。但是绕道“getSelect()->order(...)”我必须关心它。但老实说,我不知道该怎么做:(
  • 请插入你的源代码,加入等
  • 只有 Magento 内置函数,没有自己的 SQL。类 "Mage_Catalog_Block_Product_List_Toolbar" 方法 "setCollection" 集合的 SQL 代码由 Magento 生成。
  • 您还必须检查 $this->_collection 是否有您的连接字段(季节等)。可能是这个函数被多次调用。创建和设置附加标志会有所帮助。

标签: magento


【解决方案1】:

尝试使用 Zend_DB_Select 命令而不是 Magento 的 setOrder 方法

$colection->getSelect()->order(..)

例子:

->order(array('line_items_per_product DESC',
                       'product_id'));

http://framework.zend.com/manual/1.12/ru/zend.db.select.html#zend.db.select.building.order 更多示例

【讨论】:

  • 感谢您的回复。不幸的是,它不起作用。我在上面的帖子中添加了更多详细信息。
【解决方案2】:

我终于找到了解决办法。 也许其他用户需要它,所以在这里:

(可能不是最好的解决方案,但确实有效)

我创建了一个新模块并扩展了 Mage_Catalog_Block_Product_List_Toolbar。 然后我像这样覆盖“setCollection”-Method

public function setCollection($collection)
{
    $this->_collection = $collection;

    $this->_collection->setCurPage($this->getCurrentPage());

    // we need to set pagination only if passed value integer and more that 0
    $limit = (int)$this->getLimit();
    if ($limit) {
        $this->_collection->setPageSize($limit);
    }
    if ($this->getCurrentOrder()) {
        $mySource = $this->_collection->getEntity()->getAttribute('season');

        $mySource = $this->_collection->getEntity()->getAttribute('season')->getSource(); //Mage_Eav_Model_Entity_Attribute_Source_Table
        $collection = $this->_collection;
        $valueTable1    = 'season_t1';
        $valueTable2    = 'season_t2';

        $collection->getSelect()
            ->joinLeft(
                array($valueTable1 => $mySource->getAttribute()->getBackend()->getTable()),
                "e.entity_id={$valueTable1}.entity_id"
                . " AND {$valueTable1}.attribute_id='{$mySource->getAttribute()->getId()}'"
                . " AND {$valueTable1}.store_id=0",
                array()
            )
            ->joinLeft(
                array($valueTable2 => $mySource->getAttribute()->getBackend()->getTable()),
                "e.entity_id={$valueTable2}.entity_id"
                . " AND {$valueTable2}.attribute_id='{$mySource->getAttribute()->getId()}'"
                . " AND {$valueTable2}.store_id='{$collection->getStoreId()}'",
                array()
            );
        $valueExpr = $collection->getSelect()->getAdapter()
        ->getCheckSql("{$valueTable2}.value_id > 0", "{$valueTable2}.value", "{$valueTable1}.value");

        Mage::getResourceModel('eav/entity_attribute_option')
            ->addOptionValueToCollection($collection, $mySource->getAttribute(), $valueExpr);

        $sortBySeason = "FIELD(IF(season_option_value_t2.value_id IS NULL, season_option_value_t1.value, season_option_value_t2.value), ";


        $getSelectedSeason = Mage::getStoreConfig('sortproductsbyseason_options/general/current_season');

        if($getSelectedSeason == "herbst_winter"){
            $sortBySeason .= "'Frühjahr/Sommer', 'Herbst/Winter' ,''";
        }else{
            $sortBySeason .= "'Herbst/Winter', 'Frühjahr/Sommer' ,''";
        }
        $sortBySeason .= ") DESC";

        $this->_collection->getSelect()->order(new Zend_Db_Expr($sortBySeason));

        $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
    }

    return $this;
}   

【讨论】:

    【解决方案3】:

    这个呢??

    $collection = Mage::getModel('catalog/category')->load($categoryId)
        ->getProductCollection()
        ->addAttributeToSort('name', 'ASC');
    

    【讨论】:

    • 我不明白。您的代码按名称 ASC 对集合进行排序。这不是我想做的。还是我错过了什么?
    • 这应该是一个向您展示的示例,您可以在使用集合时使用 addAttributeToSort 方法。 ;-) 看看 magento wiki:magentocommerce.com/wiki/1_-_installation_and_configuration/…
    • 是的,我知道这个功能,但在这种情况下,我认为“addAttributeToSort”并不能解决问题。我不想按 DESC 或 ASC 排序 :(
    • 对不起,nicht ordentlich gelesen。 Du möchtest ja nach Jahreszeit sortieren。 :-)
    【解决方案4】:
    $products->addAttributeToSelect('*')->setOrder('cat_index_position','ASC');;        
    $products->getSelect()->order(new \Zend_Db_Expr("CASE WHEN `cat_index_position` = '0' THEN 9999 ELSE `cat_index_position` END"));        
    

    对我来说,这个答案有效, https://magento.stackexchange.com/a/121234/71417

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      相关资源
      最近更新 更多