2013-03-05 85 views
1

我正在为一家网上商店编码。产品具有默认价格,但由于它可能具有不同的属性(颜色,大小等),因此这些不同的属性也可能导致不同的价格。目前,我正在尝试生成一个mysql查询,它可以帮助我查找产品的最低和最高可能价格。使用LEFT JOIN当前将查询的结果减少到只有一行,我不知道为什么。左加入时获得最低价格/结果减少

SELECT 
    products.id AS id, 
    categories.name AS category_name, 
    MIN(product_attributes.price) AS min_price, MAX(product_attributes.price) AS max_price, 
    products.* 
FROM products 
LEFT JOIN categories ON category_id=categories.id 
LEFT JOIN product_attributes ON products.id=product_attributes.product_id 

这甚至是正确的方法吗?我不太了解MySQL,我只是试着去尝试,如果它有效,我很高兴。无论如何感谢您的帮助。

回答

2

你缺少在当前的查询GROUP BY条款,但我会建议使用子查询得到的结果:

SELECT 
    p.id AS id, 
    c.name AS category_name, 
    pa.min_price, 
    pa.max_price, 
    p.* 
FROM products p 
LEFT JOIN categories c 
    ON p.category_id = c.id 
LEFT JOIN 
(
    select MIN(product_attributes.price) min_price, 
     MAX(product_attributes.price) max_price, 
     product_id 
    from product_attributes 
    group by product_id 
) pa 
    ON p.id=pa.product_id 

的最主要的原因,我建议使用子查询是因为MySQL MySQL使用EXTENSION TO GROUP BY,它允许不执行FULL GROUP BY的行为。

MySQL中的这种扩展可能会导致SELECT列表中不在GROUP BY子句或集合函数中的列中返回意外值。

从MySQL的文档:

MySQL的扩展使用GROUP BY的,这样的选择列表可参考在GROUP BY子句中未命名的非聚合列。 ...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这非常有用,因为每个未在GROUP BY中命名的非聚合列中的所有值对于每个组都是相同的。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选值是不确定的。此外,每个组的值的选择不能通过添加ORDER BY子句来影响。结果集的排序在选择值后发生,而ORDER BY不影响服务器选择的值。

1

你需要有GROUP BY条款,

SELECT 
    products.id AS id, 
    categories.name AS category_name, 
    MIN(product_attributes.price) AS min_price, 
    MAX(product_attributes.price) AS max_price. 
    products.* 
FROM products 
LEFT JOIN categories ON category_id=categories.id 
LEFT JOIN product_attributes ON products.id=product_attributes.product_id 
GROUP BY products.id, categories.name 

,但使用在MySQL GROUP BY时要小心,因为如果ONLY_FULL_GROUP_BY默认情况下禁用的说法是完全有效的。

执行查询的正确方法是使用子查询,它可以分别获得每个产品的最低价格。

SELECT a.id AS id, 
     b.name AS category_name, 
     c.minPrice, 
     c.maxPrice, 
     a.* 
FROM products a 
     LEFT JOIN categories b 
      ON a.category_id = b.id 
     LEFT JOIN product_attributes c 
     (
      SELECT product_id, 
        MIN(product_attributes.price) minPrice, 
        MAX(product_attributes.price) maxPrice 
      FROM product_attributes 
      GROUP BY product_id 
     ) d ON a.id = c.product_id