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不太了解,我只是尝试尝试,如果它有效,我很高兴。无论如何感谢您的帮助。

4

2 回答 2

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 使用 aEXTENSION TO GROUP BY允许不强制执行FULL GROUP BY的行为。

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

来自 MySQL 文档:

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。在选择了值之后对结果集进行排序,并且 ORDER BY 不会影响服务器选择的值。

于 2013-03-05T14:12:10.687 回答
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
于 2013-03-05T14:12:06.870 回答