如何用SQL筛选仅售卖指定水果的连锁门店?
解决方案
要筛选**仅售卖Apple、Banana或Pear(无其他商品)**的门店,核心是从门店维度判断:该门店所有在售商品都属于允许列表,没有任何超出的品类。以下是两种可靠的SQL实现:
方法1:分组统计校验
通过分组后统计违规商品数量,确保为0:
SELECT s.store_id, s.store_name -- 替换为你实际需要的门店字段 FROM sl.shop_stores s JOIN sl.items i ON s.store_id = i.store_id GROUP BY s.store_id, s.store_name HAVING COUNT(CASE WHEN i.item_name NOT IN ('Apple', 'Banana', 'Pear') THEN 1 END) = 0;
逻辑说明:
- 关联门店和商品表后按门店分组
- 用
CASE语句标记所有不属于允许列表的商品,统计这类商品的数量 - 要求统计结果为0,即该门店没有售卖任何违规商品
如果需要排除完全没有售卖任何商品的空门店,可以在HAVING里再加一个条件:
HAVING COUNT(CASE WHEN i.item_name NOT IN ('Apple', 'Banana', 'Pear') THEN 1 END) = 0 AND COUNT(i.item_id) > 0; -- 确保有至少一种在售商品
方法2:子查询排除违规门店
用NOT EXISTS直接排除存在违规商品的门店,同时可选校验是否有允许商品:
SELECT s.store_id, s.store_name FROM sl.shop_stores s -- 排除有违规商品的门店 WHERE NOT EXISTS ( SELECT 1 FROM sl.items i WHERE i.store_id = s.store_id AND i.item_name NOT IN ('Apple', 'Banana', 'Pear') ) -- 可选:确保门店至少售卖一种允许的商品(去掉则会包含空门店) AND EXISTS ( SELECT 1 FROM sl.items i WHERE i.store_id = s.store_id AND i.item_name IN ('Apple', 'Banana', 'Pear') );
逻辑说明:
- 第一个
NOT EXISTS子查询检查门店是否存在任何违规商品,存在则排除 - 第二个
EXISTS子查询确保门店至少卖了一种允许的商品,避免空门店被误选
为什么之前的代码不对?
你之前的写法可能只是过滤了不符合的商品行,但没有从门店维度做校验——比如某门店同时卖Apple和Melon,旧代码会保留Apple的行、移除Melon的行,最终这个违规门店还是会出现在结果里。上面的两种方法都是从门店整体判断,只要有一个违规商品就直接排除整个门店。
内容的提问来源于stack exchange,提问作者jcoke
相关产品推荐
相关产品推荐

