通过左连接/结果减少获得最低价格

时间:2013-03-05 14:10:56

标签: mysql join

我在网上商店编码。产品具有默认价格,但由于它可能具有不同的属性(颜色,大小......),因此这些不同的属性也可能导致不同的价格。目前我正在尝试生成一个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 个答案:

答案 0 :(得分: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 :(得分: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