Php 按COND1和(COND2或COND3)筛选Magento集合

Php 按COND1和(COND2或COND3)筛选Magento集合,php,mysql,magento,Php,Mysql,Magento,如何通过attribute1=value1和(attribute2=value2或attribute3=value2)过滤Magento销售订单集合?我可以写其中{COND1}和{COND2}或{COND3},但我不能将和({COND2}或{COND3})分组 首先,这不是一个重复的AFAIK,我见过,它在版本1.3.2中工作得很好,但在企业版1.11.1中没有。这就是我想做的。。。获取在定义的日期范围内创建或更新的、状态为“正在处理”的Magento订单。以下代码在以前的版本中有效,但在我的版

如何通过attribute1=value1和(attribute2=value2或attribute3=value2)过滤Magento销售订单集合?我可以写其中{COND1}和{COND2}或{COND3},但我不能将和({COND2}或{COND3})分组

首先,这不是一个重复的AFAIK,我见过,它在版本1.3.2中工作得很好,但在企业版1.11.1中没有。这就是我想做的。。。获取在定义的日期范围内创建或更新的、状态为“正在处理”的Magento订单。以下代码在以前的版本中有效,但在我的版本中不起作用:

$orderIds = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', 'processing')
    ->addFieldToFilter(array(
        array(
            'attribute' => 'created_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
        array(
            'attribute' => 'updated_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
    ));
这是它正在生成的SQL,以及由此产生的错误:

SELECT `main_table`.* FROM `sales_flat_order` AS `main_table`
WHERE (status = 'processing') AND (Array = '')

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Array' in 'where clause' 
在深入研究代码时,我在lib/Varien/Data/Collection/Db.php中找到了
addFieldToFilter
函数

/** 
 * Add field filter to collection
 *
 * @see self::_getConditionSql for $condition
 * @param string $field
 * @param null|string|array $condition
 * @return Mage_Eav_Model_Entity_Collection_Abstract
 */
public function addFieldToFilter($field, $condition=null)
{   
    $field = $this->_getMappedField($field);
    $this->_select->where($this->_getConditionSql($field, $condition),
        null, Varien_Db_Select::TYPE_CONDITION);
    return $this;
}   

// **********************************************
// ** Different from addFieldToFilter in 1.3.2 **
// **********************************************

/** 
 * Add field filter to collection
 *
 * If $attribute is an array will add OR condition with following format:
 * array(
 *     array('attribute'=>'firstname', 'like'=>'test%'),
 *     array('attribute'=>'lastname', 'like'=>'test%'),
 * )
 *
 * @see self::_getConditionSql for $condition
 * @param string|array $attribute
 * @param null|string|array $condition
 * @return Mage_Eav_Model_Entity_Collection_Abstract
 */
public function addFieldToFilter($field, $condition=null)
{   
    $field = $this->_getMappedField($field);
    $this->_select->where($this->_getConditionSql($field, $condition));
    return $this;
}       
它看起来像是用来接受第一个参数作为数组的
addFieldToFilter
,但现在它必须是字符串。。。很有趣,所以我尝试了下面的方法,但没有运气

$orderIds = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', 'processing')
    ->addFieldToFilter('attribute', array(
        array(
            'attribute' => 'created_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
        array(
            'attribute' => 'updated_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
    ));
SELECT `main_table`.* FROM `sales_flat_order` AS `main_table`
WHERE (status = 'processing')
AND ((
    (attribute >= '2012-06-13 17:52:01' AND attribute <= '2012-06-15 17:52:01')
 OR (attribute >= '2012-06-13 17:52:01' AND attribute <= '2012-06-15 17:52:01')
))
当我更新代码时,我非常接近我想要的结果,但是我真正想要的是有CONDITION1和(CONDITION2或CONDITION3)

$orderIds=Mage::getModel('sales/order')->getCollection()
->addFieldToFilter('状态','处理')
->addAttributeToSearchFilter(数组(
排列(
'属性'=>'已在'',
'from'=>$fromDate->toString('yyyy-MM-dd HH:MM:ss'),
'至'=>$toDate->toString('yyyy-MM-dd HH:MM:ss'),
),
排列(
'属性'=>'在'',
'from'=>$fromDate->toString('yyyy-MM-dd HH:MM:ss'),
'至'=>$toDate->toString('yyyy-MM-dd HH:MM:ss'),
),
));
选择“主表”。*,
`账单“名字”,
`账单“姓氏”,
`账单“电话”,
`账单“邮政编码”,
`装运“名字”,
`shipping_o_a`.`lastname`,
`运输``电话`,
`shipping_o_a`.`邮政编码`
从'sales\u flat\u order'到'main\u table`
左键将`销售\公寓\订单\地址'作为`账单\地址'`
ON(main_table.entity_id=账单_o_a.parent_id和账单_o_a.address_type='billing')
左键将`销售\公寓\订单\地址'连接为`发货\订购地址'`
打开(main_table.entity_id=shipping_o_a.parent_id和shipping_o_a.address_type='shipping')
其中(状态=‘处理’)

或者(创建时间>='2012-06-16 16:43:38',创建时间='2012-06-16 16:43:38',更新时间,这里是我不想使用的解决方案,它通过Zend_Db方法修改SELECT语句

$orderIds = Mage::getModel('sales/order')->getCollection()
    ->getSelect();
$adapter = $orderIds->getAdapter();
$quotedFrom = $adapter->quote(
    $fromDate->toString('yyyy-MM-dd HH:mm:ss')
);
$quotedTo = $adapter->quote(
    $toDate->toString('yyyy-MM-dd HH:mm:ss')
);
$orderIds
    ->where('status = ?', 'processing')
    ->where(
        vsprintf(
            '(created_at >= %s AND created_at <= %s)'
          . ' OR (updated_at >= %s AND updated_at <= %s)',
            array(
                $quotedFrom, $quotedTo,
                $quotedFrom, $quotedTo,
            )
        )
    );
$orderIds=Mage::getModel('sales/order')->getCollection()
->getSelect();
$adapter=$orderIds->getAdapter();
$quotedFrom=$adapter->quote(
$fromDate->toString('yyyy-MM-dd HH:MM:ss')
);
$quotedTo=$adapter->quote(
$toDate->toString('yyyy-MM-dd HH:MM:ss')
);
$orderIds
->其中('status=?','processing')
->在哪里(
vsprintf(

“(在>=%s处创建,在=%s处创建,在处更新)也许是时候对核心部分进行一些更改了。我们有一些类似的问题。可能情况就是这样

(条件1)或((条件2)和(条件3)…)

如果你对它的制作方式感兴趣,试着阅读

请注意,FLAT TABLE和EAV集合使用不同的语法

向EAV集合添加或删除条件 请注意,如果要使用两个不同的属性,则在为同一属性指定或条件时,语法是不同的

使用
$collection->load(true)
测试并将指定的过滤器视为SQL(我发现这样更容易理解)

对于EAV集合,请使用
addAttributeToFilter()
addFieldToFilter()
,但第一个可以使用可选的第三个
$joinType
参数

如何为EAV集合上的一个属性添加OR筛选器:属性代码是第一个参数,条件是第二个参数

例如:
$col->addFieldToFilter('name',array(array('like'=>'M%')),array('like'=>'%O'));//(获取名称以M开头或以O结尾的项)

如何为EAV集合上的不同属性添加OR筛选器:仅传递一个参数,即带有属性的条件数组

向平面表集合添加或设置条件 在平面表集合上使用单个属性指定OR筛选器与在EAV集合上指定相同

例如:
$col->addFieldToFilter('name',array(array('like'=>'M%')),array('like'=>'%O'));//获取名称以M开头或以O结尾的项

要在OR条件中连接多个属性,语法不同于EAV集合(注意:这在Magento 1.6中被破坏)

例如:
$col->addFieldToFilter(数组('weight','name')、数组(数组('in'=>array(1,3))、数组('like'=>'M%'));

第一个属性映射到第一个条件,第二个属性映射到第二个条件,以此类推

由于这在1.6中被打破,我们可以使用
addFilter()

例如:
$col->addFilter('weight',1'或')->addFilter('weight',2'或')->addFilter('sku','ABC','or');//weight为1或2或sku为ABC

您也可以始终使用
$collection->getSelect()->或where(…)
,但您必须注意跨RDBMS的兼容性

注意:这是我多年前在tumblr上发布的东西的交叉帖子:


我认为您无法做到这一点,因为
销售/订单
映射到一个平面表格取而代之的是收集。@nevverind为什么它是一张平桌与否有关系?它不应该如此。@nevverind是一个很好的参考。我在搜索中从未遇到过这个问题。我仍然希望有办法做到这一点,但有趣的是销售订单表是EAV
$orderIds = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', 'processing')
    ->addAttributeToSearchFilter(array(
        array(
            'attribute' => 'created_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
        array(
            'attribute' => 'updated_at',
            'from' => $fromDate->toString('yyyy-MM-dd HH:mm:ss'),
            'to'   => $toDate->toString('yyyy-MM-dd HH:mm:ss'),
        ),
    ));

SELECT `main_table`.*,
       `billing_o_a`.`firstname`,
       `billing_o_a`.`lastname`,
       `billing_o_a`.`telephone`,
       `billing_o_a`.`postcode`,
       `shipping_o_a`.`firstname`,
       `shipping_o_a`.`lastname`,
       `shipping_o_a`.`telephone`,
       `shipping_o_a`.`postcode`
FROM `sales_flat_order` AS `main_table`
LEFT JOIN `sales_flat_order_address` AS `billing_o_a`
    ON (main_table.entity_id = billing_o_a.parent_id AND billing_o_a.address_type = 'billing')
LEFT JOIN `sales_flat_order_address` AS `shipping_o_a`
    ON (main_table.entity_id = shipping_o_a.parent_id AND shipping_o_a.address_type = 'shipping')
WHERE (status = 'processing')
OR (created_at >= '2012-06-16 16:43:38' AND created_at <= '2012-06-18 16:43:38')
OR (updated_at >= '2012-06-16 16:43:38' AND updated_at <= '2012-06-18 16:43:38')
$orderIds = Mage::getModel('sales/order')->getCollection()
    ->getSelect();
$adapter = $orderIds->getAdapter();
$quotedFrom = $adapter->quote(
    $fromDate->toString('yyyy-MM-dd HH:mm:ss')
);
$quotedTo = $adapter->quote(
    $toDate->toString('yyyy-MM-dd HH:mm:ss')
);
$orderIds
    ->where('status = ?', 'processing')
    ->where(
        vsprintf(
            '(created_at >= %s AND created_at <= %s)'
          . ' OR (updated_at >= %s AND updated_at <= %s)',
            array(
                $quotedFrom, $quotedTo,
                $quotedFrom, $quotedTo,
            )
        )
    );