SQL查询预约所有船只的水手,无需逐一枚举条件的实现方法
你现有代码存在两个明显问题:
- 逻辑错误:WHERE条件要求
b.color='red' AND b.color='green' AND b.color='blue',但单行数据的b.color只能对应一个值,该条件永远不成立,无法查询到任何结果。 - 可维护性差:硬编码颜色枚举,新增船只后需要同步修改查询条件。
以下是两种不需要枚举船只属性、后续新增船只无需调整查询逻辑的通用实现方案:
方案1:分组计数法(易理解,性能较好)
核心逻辑:统计每个水手预约的不重复船只数量,和船只表总数量相等的即为符合要求的水手。
SELECT s.sname FROM Sailors s INNER JOIN Reserves r ON s.sid = r.sid GROUP BY s.sid, s.sname HAVING COUNT(DISTINCT r.bid) = (SELECT COUNT(DISTINCT bid) FROM Boats);
说明:COUNT(DISTINCT r.bid)用于避免同一水手多次预约同一艘船时计数重复,子查询自动获取当前船只表的总船只数,适配船只新增/删除的场景。
方案2:双重NOT EXISTS法(关系代数除法标准实现,逻辑严谨)
核心逻辑:不存在任何一艘船,是当前水手没有预约过的,等价于该水手预约了所有船只。
SELECT DISTINCT s.sname FROM Sailors s WHERE NOT EXISTS ( SELECT b.bid FROM Boats b WHERE NOT EXISTS ( SELECT 1 FROM Reserves r WHERE r.sid = s.sid AND r.bid = b.bid ) );
说明:该方案完全基于关系匹配,不需要做计数聚合,适合数据量较大、bid唯一的场景下使用。
以上两种方案执行后都能得到符合要求的结果Dustin。
内容的提问来源于stack exchange,提问作者Al_Muzakier
相关产品推荐
相关产品推荐

