使用SQL筛选符合条件的顾客:餐厅所有在售披萨均为其喜爱且同区域
解决方案:查询满足条件的顾客列表
要找出同时满足「喜爱对应餐厅所有售卖披萨」和「与餐厅同区域」的顾客,这里提供两种直观且高效的实现方式:
方案一:使用 NOT EXISTS 子查询(推荐大数据场景)
这种方法通过反向验证逻辑来实现——确认不存在该餐厅售卖的、顾客不喜欢的披萨,以此确保顾客喜爱餐厅的所有披萨。同时通过连接操作保证顾客与餐厅同区域。
SELECT DISTINCT c.cname FROM Customers c JOIN Restaurants r ON c.area = r.area WHERE NOT EXISTS ( -- 检查:是否存在该餐厅卖的、顾客不喜欢的披萨? SELECT 1 FROM Sells s WHERE s.rname = r.rname AND NOT EXISTS ( -- 检查:顾客是否喜欢这款披萨? SELECT 1 FROM Likes l WHERE l.cname = c.cname AND l.pizza = s.pizza ) );
逻辑拆解:
JOIN Restaurants r ON c.area = r.area:先筛选出与顾客同区域的餐厅,满足第二个条件。- 外层
NOT EXISTS:如果不存在任何一款餐厅售卖的披萨是顾客不喜欢的,就说明顾客喜爱该餐厅的所有披萨,满足第一个条件。 DISTINCT:确保同一个顾客不会因为对应多个符合条件的餐厅而重复出现。
方案二:使用聚合函数对比数量
这种方法通过统计餐厅的总披萨数和顾客喜欢的该餐厅披萨数,当两者相等时,说明顾客喜爱餐厅的所有披萨。
SELECT c.cname, r.rname FROM Customers c JOIN Restaurants r ON c.area = r.area JOIN Sells s ON r.rname = s.rname LEFT JOIN Likes l ON c.cname = l.cname AND s.pizza = l.pizza GROUP BY c.cname, r.rname HAVING COUNT(s.pizza) = COUNT(l.pizza);
逻辑拆解:
- 依次连接顾客、同区域餐厅、餐厅售卖的披萨,再左连接顾客的喜欢记录(保证即使顾客不喜欢某款披萨也能保留这条记录)。
GROUP BY c.cname, r.rname:按顾客和餐厅分组。HAVING COUNT(s.pizza) = COUNT(l.pizza):餐厅的总披萨数等于顾客喜欢的该餐厅披萨数,说明没有遗漏的披萨,即顾客喜爱所有披萨。
如果只需要纯顾客列表(不需要对应餐厅信息),可以把SELECT改为SELECT DISTINCT c.cname,同时调整GROUP BY为GROUP BY c.cname即可。
内容的提问来源于stack exchange,提问作者user144794
相关产品推荐
相关产品推荐

