MySQL分组聚合查询异常:获取各卖家最低卡牌价格求助
问题分析
你遇到的两个异常问题根源如下:
- UUID全相同:关闭
ONLY_FULL_GROUP_BY后,MySQL会从每个卖家分组中随机选取一条记录的UUID值填充结果,所以所有行的UUID都一致,这完全不符合预期。 - cardkingdom价格非最低:如果确认该卖家存在更低价格,要么是当前查询的
MIN(price)逻辑被干扰(比如WHERE条件过滤了更低价格的记录),要么是原表中该卖家的最低价格确实为0.35。但核心问题还是要确保获取到对应最低价格的完整记录。
解决方案
下面提供两种标准SQL写法,无需关闭ONLY_FULL_GROUP_BY,能精准获取每个卖家最低价格对应的UUID和价格:
方法1:子查询关联(兼容所有MySQL版本)
先按卖家分组计算最低价格,再关联原表匹配对应记录:
SELECT p.uuid, p.seller, p.price FROM prices p INNER JOIN ( -- 先算出每个卖家的最低价格 SELECT seller, MIN(price) AS min_price FROM prices WHERE sellertype = 'retail' AND gametype = 'paper' AND name = 'forest' GROUP BY seller ) AS seller_min ON p.seller = seller_min.seller AND p.price = seller_min.min_price -- 重复WHERE条件过滤原表记录,避免关联到不符合条件的数据 WHERE p.sellertype = 'retail' AND p.gametype = 'paper' AND p.name = 'forest';
如果同一个卖家有多个价格相同的最低记录,这个查询会返回所有符合的记录;若只需一条,可在最外层加DISTINCT。
方法2:窗口函数(MySQL 8.0及以上版本)
用ROW_NUMBER()给每个卖家的记录按价格排序,直接取排序第一的最低价格记录:
SELECT uuid, seller, price FROM ( SELECT uuid, seller, price, -- 按卖家分组,价格升序排序,每组第一条标记为1 ROW_NUMBER() OVER (PARTITION BY seller ORDER BY price ASC) AS rn FROM prices WHERE sellertype = 'retail' AND gametype = 'paper' AND name = 'forest' ) AS ranked_prices WHERE rn = 1;
如果想保留同价的所有最低记录,把ROW_NUMBER()换成RANK()即可。
重要建议
不要关闭ONLY_FULL_GROUP_BY,这个模式是SQL标准的一部分,能强制分组查询的逻辑严谨性,避免出现随机、非预期的结果。始终使用符合标准的写法保证数据准确性。
内容的提问来源于stack exchange,提问作者erotski
相关产品推荐
相关产品推荐

