如何使用GROUP BY筛选含最小字段值的行?MySQL查询问题求助
构建MySQL查询遇到困境(重新发布)
大家好,之前我发布过这个问题并收到了答复,但发现返回的数据完全不符合我的需求,所以重新整理细节后再发一次,希望能得到准确的解决方案。
我的需求
我有一张记录用户商品出价的表,结构和示例数据如下,需要为每个item_id找出出价最高(bid_price最大)的那条完整记录,包括对应的id和user_id字段。
示例数据表
| id | item_id | user_id | bid_price |
|---|---|---|---|
| 1 | 1 | 11 | 1 |
| 2 | 1 | 12 | 2 |
| 3 | 1 | 13 | 3 |
| 4 | 1 | 14 | 1 |
| 5 | 1 | 15 | 4 |
| 6 | 2 | 16 | 2 |
| 7 | 2 | 17 | 1 |
| 8 | 3 | 18 | 2 |
此前收到的答复
之前有朋友给了我这样的查询语句:
SELECT item_id, MAX(bid_price) AS highest_bid FROM bids GROUP BY item_id;
为什么这个答复解决不了我的问题
- 这个查询只返回了每个商品的
item_id和最高出价金额,完全没给出我需要的对应记录的id和user_id——我要的是完整的出价记录,不是单纯的最高价格数值。 - 如果我强行把
id或user_id加到SELECT字段里,在MySQL严格模式下直接会报错;就算关闭严格模式,返回的id和user_id也不是对应最高出价那条的,是随机取的,根本不符合业务要求。
我期望的输出结果
我想要得到的正确结果应该是这样的:
| id | item_id | user_id | bid_price |
|---|---|---|---|
| 5 | 1 | 15 | 4 |
| 6 | 2 | 16 | 2 |
| 8 | 3 | 18 | 2 |
正确的解决方案
这里给两种可行的方法,适配不同的MySQL版本:
方法1:使用窗口函数(MySQL 8.0及以上版本)
窗口函数可以很方便地给每个商品分组的记录按出价排序,然后筛选出排名第一的那条:
SELECT id, item_id, user_id, bid_price FROM ( SELECT id, item_id, user_id, bid_price, ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY bid_price DESC) AS rn FROM bids ) AS ranked_bids WHERE rn = 1;
如果同一个商品有多个相同的最高出价,这个方法默认会返回id最小的那条;如果想指定取最新的出价记录,可以把排序规则改成ORDER BY bid_price DESC, id DESC。
方法2:关联子查询(兼容MySQL 5.x版本)
如果你的MySQL版本不支持窗口函数,可以用子查询匹配每个商品的最高出价,再关联获取完整记录:
SELECT b1.* FROM bids b1 WHERE b1.bid_price = ( SELECT MAX(bid_price) FROM bids b2 WHERE b2.item_id = b1.item_id );
注意:这个方法会返回同一个商品所有出价等于最高价格的记录,如果只需要一条,可以在末尾加上LIMIT 1,或者结合ORDER BY id DESC来筛选最新的那条。
内容的提问来源于stack exchange,提问作者Sergej
相关产品推荐
相关产品推荐

