magento - 如何在 Magento 中将 AND 过滤器/条件添加到 OR 条件?

标签 magento filter

如何使用集合过滤器实现以下目标?

SELECT * FROM products WHERE (name like '%blah%' and name like 
    '%yes%') or (description like '%blah%' and description like '%yes%');

或者由于某种原因这是一种不好的做法?

addFieldToFilter 应用于集合时执行 AND,并且在每个集合中您可以实现 OR,但这仅允许:

(x OR y) AND (w OR z) 

但不是

(x AND y) OR (w AND z)

我错过了什么吗?

最佳答案

不,我不相信你错过了任何东西。我不久前遇到了类似的问题并使用了 getSelect()->where()解决它。

从您的查询开始:

SELECT * FROM products WHERE (name like '%blah%' and name like 
'%yes%') or (description like '%blah%' and description like '%yes%');

首先,我创建了一个集合并使用 OR数组方法来获取查询。

$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addFieldToFilter(array(
                              array('attribute' => 'name', 'like' => '%blah%'),
                              array('attribute' => 'name', 'like' => '%yes%')
                              ));
$collection->addFieldToFilter(array(
                              array('attribute' => 'description', 'like' => '%blah%'),
                              array('attribute' => 'description', 'like' => '%yes%')
                              ));
$collection->load(true); // To dump the sql as text

这导致了以下输出:

SELECT `e`.*, IF(at_name.value_id > 0, at_name.value, at_name_default.value) AS `name`, IF(at_description.value_id > 0, at_description.value, at_description_default.value) AS `description` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_product_entity_varchar` AS `at_name_default` ON (`at_name_default`.`entity_id` = `e`.`entity_id`) AND (`at_name_default`.`attribute_id` = '96') AND `at_name_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_varchar` AS `at_name` ON (`at_name`.`entity_id` = `e`.`entity_id`) AND (`at_name`.`attribute_id` = '96') AND (`at_name`.`store_id` = 1) INNER JOIN `catalog_product_entity_text` AS `at_description_default` ON (`at_description_default`.`entity_id` = `e`.`entity_id`) AND (`at_description_default`.`attribute_id` = '97') AND `at_description_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_text` AS `at_description` ON (`at_description`.`entity_id` = `e`.`entity_id`) AND (`at_description`.`attribute_id` = '97') AND (`at_description`.`store_id` = 1) 
WHERE ((IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%blah%') OR (IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%yes%')) AND ((IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%blah%') OR (IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%yes%'))

您会注意到 WHERE语句几乎与您描述的位置相同,除了 ORAND是相反的。

我复制了WHERE查询的一部分并添加了额外的 getSelect()->where()像这样的集合行:

$collection = Mage::getModel('catalog/product')->getCollection();

// I added these lines to ensure that the collection would load 
// the fields and do the necessary joins to pull the data
$collection->addFieldToFilter('name');          
$collection->addFieldToFilter('description');

// I'm using the same WHERE statement but I have set the ANDs and ORs
// to match your requirements

$collection->getSelect()->where(" (IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%blah%') AND (IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%yes%')) OR ((IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%blah%') AND (IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%yes%')");

$collection->load(true); // To dump the sql as text again

结果输出是:

SELECT `e`.*, IF(at_name.value_id > 0, at_name.value, at_name_default.value) AS `name`, IF(at_description.value_id > 0, at_description.value, at_description_default.value) AS `description` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_product_entity_varchar` AS `at_name_default` ON (`at_name_default`.`entity_id` = `e`.`entity_id`) AND (`at_name_default`.`attribute_id` = '96') AND `at_name_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_varchar` AS `at_name` ON (`at_name`.`entity_id` = `e`.`entity_id`) AND (`at_name`.`attribute_id` = '96') AND (`at_name`.`store_id` = 1) INNER JOIN `catalog_product_entity_text` AS `at_description_default` ON (`at_description_default`.`entity_id` = `e`.`entity_id`) AND (`at_description_default`.`attribute_id` = '97') AND `at_description_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_text` AS `at_description` ON (`at_description`.`entity_id` = `e`.`entity_id`) AND (`at_description`.`attribute_id` = '97') AND (`at_description`.`store_id` = 1) 
WHERE (IF(at_name.value_id > 0, at_name.value, at_name_default.value) = '') AND (IF(at_description.value_id > 0, at_description.value, at_description_default.value) = '') AND ( (IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%blah%') AND (IF(at_name.value_id > 0, at_name.value, at_name_default.value) LIKE '%yes%')) OR ((IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%blah%') AND (IF(at_description.value_id > 0, at_description.value, at_description_default.value) LIKE '%yes%'))

where()getSelect()可以缩短为:

(`name` like '%blah%' and `name` like '%yes%') or (`description` like '%blah%' and `description` like '%yes%');

如果我的观点离谱太远,或者如果您知道不使用此方法也能实现相同目标的方法,请任何其他 Magento 人员随时纠正我。

第一个!

关于magento - 如何在 Magento 中将 AND 过滤器/条件添加到 OR 条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15040529/

相关文章:

Magento 管理网格将数据从 Action 发送到 Controller

javascript - iOS UIWebView,如何阻止加载特定的 URL 模式?

filter - 隐藏筛选器中的值 - Tableau

javascript - 基于 n 嵌套数组按名称过滤

symfony - Assetic Symfony2 less+compress 过滤器

java - 如何在Hibernate多对多映射中过滤数据

css - 是否可以通过子主题在 Magento 2 中使用 vanilla CSS 文件?

zend-framework - Magento/Zend 不允许符号链接(symbolic link)

php - magento 删除管理菜单项

php - Magento 产品列表 - 按产品类型排序(可配置然后简单)