构建MySQL查询:获取指定item_id集合的最低出价行
嘿,这个需求我在项目里经常碰到,给你整理几种实用的解法,适配不同的数据库场景:
核心思路
要实现“每个指定item_id取bid_price最小的行”,本质是先找到每个item_id对应的最低出价,再关联回原表拿到完整的行数据。这里分两种主流实现方式:
方法一:窗口函数(推荐,支持现代数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),用RANK()或ROW_NUMBER()是最简洁的方案:
场景1:保留所有同最低价的行
用RANK()会给同一item_id下出价相同的行分配相同的排名,这样能取出所有最低价的记录:
SELECT id, item_id, user_id, bid_price FROM ( SELECT *, RANK() OVER (PARTITION BY item_id ORDER BY bid_price ASC) AS rank_num FROM your_table_name WHERE item_id IN (1, 2, 3) -- 替换成你的目标item_id集合 ) ranked_data WHERE rank_num = 1;
场景2:只取一条最低价的行(同价时按规则筛选)
如果只需要每个item_id返回一条记录,用ROW_NUMBER(),它会给同价的行分配不同的序号,你可以额外指定排序规则来确定选哪条:
SELECT id, item_id, user_id, bid_price FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY bid_price ASC, id ASC) AS row_num FROM your_table_name WHERE item_id IN (1, 2, 3) ) numbered_data WHERE row_num = 1;
这里我加了id ASC来保证同价时选id最小的行,你也可以换成其他业务需要的字段排序。
方法二:关联子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用子查询先算出每个item_id的最低出价,再关联原表:
SELECT t1.* FROM your_table_name t1 INNER JOIN ( SELECT item_id, MIN(bid_price) AS min_bid_price FROM your_table_name WHERE item_id IN (1, 2, 3) GROUP BY item_id ) t2 ON t1.item_id = t2.item_id AND t1.bid_price = t2.min_bid_price;
这个方法和RANK()的效果一致,会返回所有同最低价的行。
测试示例数据的结果
用你提供的示例数据跑RANK()的查询,会得到以下结果:
| item_id | user_id | bid_price |
|---|---|---|
| 1 | 11 | 1 |
| 1 | 14 | 1 |
| 2 | 17 | 1 |
| 3 | 18 | 2 |
如果用ROW_NUMBER(),则会返回id=1、7、8这三条记录(因为加了id ASC排序,优先选id更小的同价行)。
内容的提问来源于stack exchange,提问作者Sergej
相关产品推荐
相关产品推荐

