MySQL查询:获取同款商品最低价格的对应行数据
解决相同商品名称下取最低价格完整记录的问题
看起来你需要的是每个商品名称对应的最低有效价格的完整记录,而你当前的查询只计算了最低价格,但其他字段(比如ID、provider_id)可能无法正确关联到那条价格最低的记录——因为GROUP BY name后,非聚合字段的返回结果在MySQL中是不确定的(如果开启了ONLY_FULL_GROUP_BY模式,你的查询甚至会直接报错)。
先明确有效价格的逻辑:从你的示例数据来看,是取new_price、old_price、price三个字段中的非空值,然后找出每个商品名称下的最小值对应的完整记录。下面提供两种可行的解决方案:
方案一:使用窗口函数(推荐,MySQL 8.0+)
窗口函数是处理这类"分组取最值"场景最清晰的方式,我们可以用ROW_NUMBER()给每个商品名称下的记录按有效价格排序,然后取排序第一的那条:
SELECT ID, `Product Name`, effective_price AS price, provider_id, `condition` FROM ( SELECT ID, `Product Name`, provider_id, `condition`, -- 用COALESCE简化多字段非空取值逻辑,和你原来的IF嵌套效果一致 COALESCE(new_price, old_price, price) AS effective_price, -- 按商品名称分组,按有效价格升序排序,价格最低的行标记为1 ROW_NUMBER() OVER ( PARTITION BY `Product Name` ORDER BY COALESCE(new_price, old_price, price) ASC ) AS rn FROM products ) AS ranked_products WHERE rn = 1;
逻辑说明:
- 内层子查询:先为每条记录计算
effective_price(取三个价格字段中第一个非空的值),同时用ROW_NUMBER()给每个商品分组内的记录按价格从小到大排序,价格最低的记录会被标记为rn=1。 - 外层查询:只筛选出
rn=1的记录,就是每个商品名称下价格最低的完整记录。
方案二:兼容旧版本MySQL(无窗口函数支持)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用关联子查询的方式实现:
SELECT p.ID, p.`Product Name`, COALESCE(p.new_price, p.old_price, p.price) AS price, p.provider_id, p.`condition` FROM products p WHERE COALESCE(p.new_price, p.old_price, p.price) = ( -- 子查询算出当前商品名称的最低有效价格 SELECT MIN(COALESCE(new_price, old_price, price)) FROM products WHERE `Product Name` = p.`Product Name` );
逻辑说明:
子查询先计算出每个商品名称对应的最低有效价格,外层查询再找到对应商品名称中有效价格等于这个最低值的记录。如果存在多条价格相同且都是最低的记录,这个查询会返回所有符合条件的记录;如果只需要一条,可以在语句末尾加上LIMIT 1。
验证结果
用你提供的示例数据测试上述查询,会得到你期望的结果:
+----------+--------------------+-------+--------------+-------------+ | ID | Product Name | price | provider_id | condition | +----------+--------------------+-------+--------------+-------------+ | 23 | samsung tv 32 | 300 | 6 | used | | 23 | smart watch | 100 | 6 | used | +----------+--------------------+-------+--------------+-------------+
内容的提问来源于stack exchange,提问作者user5448157
相关产品推荐
相关产品推荐

