如何从两列中获取最小值及对应store_id?SQL查询结果异常求助
解决SQL查询中最低价格对应store_id不正确的问题
我来帮你搞定这个问题!你的查询之所以拿不到正确的store_id,核心问题有两个:
- 当使用
MIN()这类聚合函数时,SELECT语句里的非聚合列(比如store_id)不会自动和聚合结果关联,数据库会随机返回某一行的store_id,自然和最低价格不匹配; - 原查询里的
IF函数写法有误,缺少了false分支,导致当没有特价时会返回NULL,没法正确计算最低价格。
下面给你两种靠谱的解决方案:
方法一:子查询+关联匹配
先通过子查询算出每个商品的最低价格,再关联回原表找到对应价格的店铺信息:
SELECT gi.id, gi.category, gc.name AS cat, gi.name AS itemName, gp.price AS price, gp.store_id, gs.name AS storeName FROM grocery_item gi LEFT JOIN grocery_category gc ON gc.id = gi.category LEFT JOIN ( -- 子查询:计算每个商品的最低价格(优先取特价,无特价则取原价) SELECT grocery_item_id, MIN(CASE WHEN price_special > 0 THEN price_special ELSE price_base END) AS min_price FROM grocery_price GROUP BY grocery_item_id ) min_prices ON min_prices.grocery_item_id = gi.id -- 关联回价格表,找到对应最低价格的记录 LEFT JOIN grocery_price gp ON gp.grocery_item_id = gi.id AND (CASE WHEN gp.price_special > 0 THEN gp.price_special ELSE gp.price_base END) = min_prices.min_price LEFT JOIN grocery_store gs ON gs.id = gp.store_id;
注意:如果同一个商品有多个店铺价格相同且都是最低价,这个查询会返回多行,你可以根据需求添加DISTINCT或者进一步筛选。
方法二:窗口函数排序取第一
用ROW_NUMBER()窗口函数给每个商品的价格行按价格升序排序,取排名第一的行就是最低价格对应的记录:
SELECT id, category, cat, itemName, price, store_id, storeName FROM ( SELECT gi.id, gi.category, gc.name AS cat, gi.name AS itemName, -- 计算实际售卖价格 CASE WHEN gp.price_special > 0 THEN gp.price_special ELSE gp.price_base END AS price, gp.store_id, gs.name AS storeName, -- 按商品分组,价格升序排序,排名1的就是最低价 ROW_NUMBER() OVER (PARTITION BY gi.id ORDER BY CASE WHEN gp.price_special > 0 THEN gp.price_special ELSE gp.price_base END ASC) AS rn FROM grocery_item gi LEFT JOIN grocery_category gc ON gc.id = gi.category LEFT JOIN grocery_price gp ON gp.grocery_item_id = gi.id LEFT JOIN grocery_store gs ON gs.id = gp.store_id ) ranked WHERE rn = 1;
如果想保留所有同价的店铺,把ROW_NUMBER()换成RANK()即可,这样同价的行排名都会是1。
内容的提问来源于stack exchange,提问作者bp163
相关产品推荐
相关产品推荐

