0

我正在寻找一个更优雅的解决方案来解决与 GROUP BY 结合使用的 MySQL MIN() 问题。

我有两张桌子:

  1. 产品(id,group_id)
  2. product_attributes (product_id, attribute_id, value)

我希望从某个产品组的每个金属组(attribute_id = 40)中选择最便宜的金属。

以下查询有效,但我很确定它本来可以写得更好。

SELECT metal.product_id, metal.value AS `metal`, `price`.value AS `price`
FROM
    product_attributes metal
INNER JOIN
    (
        SELECT metal.value AS `metal`, MIN(price.value) AS `price`
        FROM 
            product_attributes metal
        LEFT JOIN 
            product_attributes price
        ON metal.product_id = price.product_id
        INNER JOIN products p
        ON p.id = metal.product_id
        WHERE
            metal.attribute_id = 40 AND
            price.attribute_id = 37 AND
            p.group_id = 1
        GROUP BY
            metal.value
        ORDER BY metal ASC, price DESC
    ) AS d ON
    d.metal = metal.value
LEFT JOIN
    product_attributes price ON
    metal.product_id = price.product_id AND price.attribute_id = 37
INNER JOIN
    products p ON
    p.id = metal.product_id
WHERE
    metal.attribute_id = 40
    AND d.price = price.value
    AND p.group_id = 1
GROUP BY
    metal.value
ORDER BY
    metal.value ASC,
    price.value DESC;
4

2 回答 2

0

解决方案终于比我简单了。我在内部查询中按价格对数据进行了排序,因此在 GROUP BY 之前强制进行排序,这样我就得到了我需要的东西(每个金属组中最便宜的产品)。

SELECT * FROM
            (
                SELECT metal.enum_id AS `metal`, metal.product_id FROM product_attributes metal
                LEFT JOIN product_attributes price ON metal.product_id = price.product_id AND price.attribute_id = 37
                INNER JOIN products p ON p.id = metal.product_id
                WHERE
                    metal.attribute_id = 40 AND
                    p.group_id = 1 AND
                    p.id NOT IN (SELECT DISTINCT product_id FROM product_attributes WHERE (attribute_id=162 OR attribute_id=204 OR attribute_id=205) AND `value`=1)
                ORDER BY price.value+'0' ASC 
            ) AS s
            GROUP BY metal
于 2013-04-17T13:08:16.903 回答
0

我想你可以把它写成一个group by声明:

  SELECT metal.value AS `metal`, metal.product_id, MIN(price.value) AS `price`
  FROM product_attributes metal LEFT JOIN 
       product_attributes price
       ON metal.product_id = price.product_id
       INNER JOIN products p
       ON p.id = metal.product_id
  WHERE metal.attribute_id = 40 AND
        price.attribute_id = 37 AND
        p.group_id = 1
  GROUP BY metal
  order by metal, price

这有效,假设product_id每个metal.value. 如果有多个这样的产品 id,那么您需要重新加入属性表:

SELECT metal.product_id, metal.value AS `metal`, d.`price`
FROM (SELECT metal.value AS `metal`, MIN(price.value) AS `price`
      FROM product_attributes metal LEFT JOIN 
           product_attributes price
           ON metal.product_id = price.product_id
           INNER JOIN products p
           ON p.id = metal.product_id
      WHERE metal.attribute_id = 40 AND
            price.attribute_id = 37 AND
            p.group_id = 1
      GROUP BY metal
    ) d join
    product_attributes metal
    ON d.metal = metal.value
ORDER BY metal.value ASC, d.price DESC

您可能还需要where和 附加连接。这取决于您的数据结构。

于 2013-04-14T20:43:54.330 回答