带WHERE子句时,获取另一列最小值对应关联值的MySQL实现
解决MySQL 5.5中仅写一次筛选条件获取产品最低价格对应记录的问题
首先明确你的核心需求:先筛选出符合用户条件的记录,再在这些记录中找到每个产品的最低价格对应的完整记录(保证price和fee来自同一条数据),且筛选条件只需编写一次。针对MySQL 5.5不支持窗口函数(比如ROW_NUMBER())的限制,这里提供两种可行方案:
方案一:使用临时表(推荐,筛选条件仅写一次)
临时表可以先存储所有符合筛选条件的记录,后续的最低价格计算都基于这个临时表,完全避免重复编写筛选条件:
-- 1. 创建临时表,存储符合筛选条件的所有记录(这里只写一次筛选条件) CREATE TEMPORARY TABLE filtered_prices SELECT product_id, price_id, a, b, c, price, fee FROM prices WHERE c = 20; -- 替换成你的实际筛选条件,比如b=300等 -- 2. 从临时表中找出每个产品的最低价格,并关联获取对应完整记录 SELECT fp.* FROM filtered_prices fp JOIN ( SELECT product_id, MIN(price) AS min_price FROM filtered_prices GROUP BY product_id ) AS product_min_prices ON fp.product_id = product_min_prices.product_id AND fp.price = product_min_prices.min_price; -- 可选:会话结束后临时表会自动删除,也可以手动删除 DROP TEMPORARY TABLE filtered_prices;
方案优势:
- 筛选条件仅需在创建临时表时编写一次,后续操作无需重复维护
- 逻辑清晰,临时表的复用性强,适合复杂筛选场景
- 性能友好,尤其是数据量较大时,临时表的查询效率更高
方案二:使用嵌套子查询(无需临时表,筛选条件需同步修改两次)
如果不想使用临时表,可以通过嵌套子查询实现,虽然筛选条件会出现两次,但逻辑一致,维护时同步修改即可:
SELECT p.* FROM prices p WHERE p.c = 20 -- 筛选条件 AND p.price = ( SELECT MIN(p2.price) FROM prices p2 WHERE p2.product_id = p.product_id AND p2.c = 20 -- 与外层筛选条件保持一致 );
为什么之前Gordon的方案返回0行?
你提到使用SELECT p.* FROM prices p WHERE p.price = ( SELECT min( p2.price ) FROM prices p2 WHERE p2.product_id = p.product_id ) AND b = 300返回0行,原因是:
这个逻辑是先找整个产品的最低价格,再筛选该价格对应的记录是否符合b=300。而产品1的最低价格500对应的b值是100,不符合b=300的条件,所以没有符合条件的记录返回。
而你的真实需求是先筛选符合b=300的记录,再在这些记录里找最低价格,这两种逻辑的差异导致了结果不同,这也是为什么需要把筛选条件应用到子查询中的原因。
内容的提问来源于stack exchange,提问作者sauntimo
相关产品推荐
相关产品推荐

