我正在寻找一个更优雅的解决方案,解决我在使用与GROUP BY一起使用的MySQL MIN()时遇到的问题。
我有两张桌子:
我希望从某个产品组中选择每个金属组中最便宜的金属(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;
答案 0 :(得分: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
和其他联接。这取决于数据的结构。
答案 1 :(得分: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