工作环境摘要
我正在一个我们有客户和经销商的网站上工作。每个经销商都可以为产品定价。
生产收集数据具有另一个具有该卖方价格的产品的重复记录(克隆产品)。例如,如果主目录有IPHONE 6S。超过5个交易Iphone 6s的经销商可以有自己的价格。克隆产品会创建与卖家ID
相关的新产品ID要求
我需要获得具有最低价格的经销商的类别明智产品列表。还需要根据最低价格对该列表进行排序。
我尝试了什么
目前我可以根据类别列出所有价格最低的产品。
$productCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('sellingprice')
->setStoreId($storeId)
->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
->addAttributeToFilter('category_id', array('in' => $_POST['category_id']))
->addAttributeToFilter('status', array('eq' => 1))
->addAttributeToFilter('dis_continue', array('eq' => 0));
$productCollection->addAttributeToFilter('seller_id', array('in' => $seller_list));
$productCollection->addExpressionAttributeToSelect(
'lowest_price', 'IF(({{special_from_date}}<=now() AND {{special_to_date}}>=now() OR {{special_from_date}} IS NULL AND {{special_price}}>0),{{special_price}},IF({{sellingprice}}>0,{{sellingprice}},{{price}}))', array('special_from_date', 'special_to_date', 'special_price', 'sellingprice', 'price'));
$productCollection->getSelect()->columns('MIN(IF((IF(at_special_from_date.value_id > 0, at_special_from_date.value, at_special_from_date_default.value)<=now() AND IF(at_special_to_date.value_id > 0, at_special_to_date.value, at_special_to_date_default.value)>=now() OR IF(at_special_from_date.value_id > 0, at_special_from_date.value, at_special_from_date_default.value) IS NULL AND at_special_price.value>0),at_special_price.value,IF(at_sellingprice.value>0,at_sellingprice.value,at_price.value))) as l_price')->group('product_name');
我发现最低的销售价格,特价,经销商的mrp。
使用Group按产品名称对所有数据进行分组,获得最低价格的MINIMUM,按照最低价格进行分类。
问题
正如我解释的那样,我正在使用GROUP BY名称,以便我可以拥有独特的产品,但我无法获得价格最低的相关卖家的PRODUCT ID。我需要获得最低价格的卖家ID
GROUP BY始终返回第一个ROW,但MIN()函数给出最低价格。 First ROW没有最低价格的相关PRODUCT ID .....
编辑 - MYSQL QUERY
SELECT `e`.*,
`at_category_id`.`category_id`,
IF(
at_status.value_id > 0,
at_status.value,
at_status_default.value
) AS `status`,
`at_dis_continue`.`value` AS `dis_continue`,
`at_seller_id`.`value` AS `seller_id`,
`at_popular_product`.`value` AS `popular_product`,
IF(
at_special_from_date.value_id > 0,
at_special_from_date.value,
at_special_from_date_default.value
) AS `special_from_date`,
IF(
at_special_to_date.value_id > 0,
at_special_to_date.value,
at_special_to_date_default.value
) AS `special_to_date`,
`at_special_price`.`value` AS `special_price`,
`at_sellingprice`.`value` AS `sellingprice`,
`at_price`.`value` AS `price`,
IF(
(
IF(
at_special_from_date.value_id > 0,
at_special_from_date.value,
at_special_from_date_default.value
) <= NOW() AND IF(
at_special_to_date.value_id > 0,
at_special_to_date.value,
at_special_to_date_default.value
) >= NOW() OR IF(
at_special_from_date.value_id > 0,
at_special_from_date.value,
at_special_from_date_default.value
) IS NULL AND at_special_price.value > 0
),
at_special_price.value,
IF(
at_sellingprice.value > 0,
at_sellingprice.value,
at_price.value
)
) AS `lowest_price`,
`at_name`.`value` AS `name`,
`at_name`.`value` AS `product_name`,
MIN(
IF(
(
IF(
at_special_from_date.value_id > 0,
at_special_from_date.value,
at_special_from_date_default.value
) <= NOW() AND IF(
at_special_to_date.value_id > 0,
at_special_to_date.value,
at_special_to_date_default.value
) >= NOW() OR IF(
at_special_from_date.value_id > 0,
at_special_from_date.value,
at_special_from_date_default.value
) IS NULL AND at_special_price.value > 0
),
at_special_price.value,
IF(
at_sellingprice.value > 0,
at_sellingprice.value,
at_price.value
)
)
) AS `l_price`
FROM
`catalog_product_entity` AS `e`
LEFT JOIN
`catalog_category_product` AS `at_category_id` ON(
at_category_id.`product_id` = e.entity_id
)
INNER JOIN
`catalog_product_entity_int` AS `at_status_default` ON(
`at_status_default`.`entity_id` = `e`.`entity_id`
) AND(
`at_status_default`.`attribute_id` = '96'
) AND `at_status_default`.`store_id` = 0
LEFT JOIN
`catalog_product_entity_int` AS `at_status` ON(
`at_status`.`entity_id` = `e`.`entity_id`
) AND(`at_status`.`attribute_id` = '96') AND(`at_status`.`store_id` = 1)
INNER JOIN
`catalog_product_entity_int` AS `at_dis_continue` ON(
`at_dis_continue`.`entity_id` = `e`.`entity_id`
) AND(
`at_dis_continue`.`attribute_id` = '261'
) AND(`at_dis_continue`.`store_id` = 0)
INNER JOIN
`catalog_product_entity_varchar` AS `at_seller_id` ON(
`at_seller_id`.`entity_id` = `e`.`entity_id`
) AND(
`at_seller_id`.`attribute_id` = '134'
) AND(`at_seller_id`.`store_id` = 0)
INNER JOIN
`catalog_product_entity_varchar` AS `at_popular_product` ON(
`at_popular_product`.`entity_id` = `e`.`entity_id`
) AND(
`at_popular_product`.`attribute_id` = '1078'
) AND(
`at_popular_product`.`store_id` = 0
)
LEFT JOIN
`catalog_product_entity_datetime` AS `at_special_from_date_default` ON(
`at_special_from_date_default`.`entity_id` = `e`.`entity_id`
) AND(
`at_special_from_date_default`.`attribute_id` = '77'
) AND `at_special_from_date_default`.`store_id` = 0
LEFT JOIN
`catalog_product_entity_datetime` AS `at_special_from_date` ON(
`at_special_from_date`.`entity_id` = `e`.`entity_id`
) AND(
`at_special_from_date`.`attribute_id` = '77'
) AND(
`at_special_from_date`.`store_id` = 1
)
LEFT JOIN
`catalog_product_entity_datetime` AS `at_special_to_date_default` ON(
`at_special_to_date_default`.`entity_id` = `e`.`entity_id`
) AND(
`at_special_to_date_default`.`attribute_id` = '78'
) AND `at_special_to_date_default`.`store_id` = 0
LEFT JOIN
`catalog_product_entity_datetime` AS `at_special_to_date` ON(
`at_special_to_date`.`entity_id` = `e`.`entity_id`
) AND(
`at_special_to_date`.`attribute_id` = '78'
) AND(
`at_special_to_date`.`store_id` = 1
)
LEFT JOIN
`catalog_product_entity_decimal` AS `at_special_price` ON(
`at_special_price`.`entity_id` = `e`.`entity_id`
) AND(
`at_special_price`.`attribute_id` = '76'
) AND(`at_special_price`.`store_id` = 0)
LEFT JOIN
`catalog_product_entity_decimal` AS `at_sellingprice` ON(
`at_sellingprice`.`entity_id` = `e`.`entity_id`
) AND(
`at_sellingprice`.`attribute_id` = '143'
) AND(`at_sellingprice`.`store_id` = 0)
LEFT JOIN
`catalog_product_entity_decimal` AS `at_price` ON(
`at_price`.`entity_id` = `e`.`entity_id`
) AND(`at_price`.`attribute_id` = '75') AND(`at_price`.`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` = '71') AND(`at_name`.`store_id` = 0)
WHERE
(
at_category_id.category_id IN('119')
) AND(
IF(
at_status.value_id > 0,
at_status.value,
at_status_default.value
) = 1
) AND(at_dis_continue.value = 0) AND(at_seller_id.value IN('1065')) AND(
at_popular_product.value IN('Yes',
'No')
)
GROUP BY
`product_name`
如果IN MAGENTO
有任何办法,请提供帮助答案 0 :(得分:5)
我担心我对Magento本身并不熟悉直接帮助您的代码,但更一般地说,这是SQL SELECT
查询的常见问题。
首先,一个重要的说明:使用GROUP BY
时,查询的SELECT
部分中未包含在GROUP BY
子句中的任何字段可能都不合法。结果取决于您的服务器版本和/或ONLY_FULL_GROUP_BY
SQL模式。
更重要的是,假设您的服务器/配置支持它,选择GROUP BY
子句中未包含的字段意味着您从组中的任意行获取值,不是第一行 。从MySQL文档中的MySQL Handling of GROUP BY page:
在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的,这可能不是您想要的。
实现您一直寻找的行为的一种方法一直适用于我,方法是使用计数器和子查询来排序和过滤您的子组。这比GROUP BY
提供了更高的控制水平(尽管你做了一些性能牺牲):
SELECT @num := IF(products_name=@last_products_name, @num + 1, 1) b, (@last_products_name := products_name) AS last_pname, t1.*
FROM (
SELECT p.products_id, p.products_name, p.selling_price
FROM products p
WHERE p.category_id = 123
ORDER BY p.products_name,
p.selling_price ASC
) t1, (SELECT @num := 0, @last_products_name := 0) d
HAVING b=1;
要更清楚地了解其工作原理,请运行不带HAVING
子句的查询。你得到这样的结果:
+------+------------+-------------+---------------+---------------+
| b | last_pname | products_id | products_name | selling_price |
+------+------------+-------------+---------------+---------------+
| 1 | Bar | 8 | Bar | 5.00 |
| 2 | Bar | 2 | Bar | 12.00 |
| 3 | Bar | 4 | Bar | 14.00 |
| 1 | Fizz | 3 | Fizz | 30.00 |
| 2 | Fizz | 5 | Fizz | 70.00 |
| 3 | Fizz | 7 | Fizz | 100.00 |
| 1 | Foo | 1 | Foo | 10.00 |
| 2 | Foo | 6 | Foo | 18.00 |
+------+------------+-------------+---------------+---------------+
b
列显示@num
变量的值,该变量对于一组名称相同的产品中的每一行递增,并在每次当前行中的产品名称不相等时重置到最后一个的名字。添加HAVING b=1
子句意味着我们只能获得每组中最便宜的产品。
ORDER BY
时的潜在问题!当我上次使用MySQL时,上述解决方案将起作用(我想现在仍然如此)。但是,这实际上不是标准的SQL行为。数据库服务器更严格地遵守标准(例如MariaDB)will ignore an ORDER BY
clause contained within a sub-query,除非子查询还具有LIMIT
子句。因此,如果您使用的是MariaDB,则需要强制服务器通过包含ORDER BY
来尊重LIMIT
。我以前使用过的技术(如前一个链接的评论中所述)是指定一个非常大的LIMIT
值:
SELECT @num := IF(products_name=@last_products_name, @num + 1, 1) b, (@last_products_name := products_name) AS last_pname, t1.*
FROM (
SELECT p.products_id, p.products_name, p.selling_price
FROM products p
WHERE p.category_id = 123
ORDER BY p.products_name,
p.selling_price ASC
LIMIT 18446744073709551615 -- LIMIT clause forces sub-query ORDER BY
) t1, (SELECT @num := 0, @last_products_name := 0) d
HAVING b=1;
我希望有所帮助。