如何用SQL找出供应了另一供应商所有零件的供应商编号?
找出供应指定供应商所有零件的SQL解决方案
没问题,我来帮你搞定这个SQL查询!你要找的是供应了S2所有零件的供应商编号(SNO),也就是这些供应商的零件集合必须完全包含S2的全部零件。结合你的示例数据,S2供应的零件是P1和P2,所以S1、S4符合要求,S3只供应了P1就会被排除。下面给你两种实用的解决方案:
方法一:使用NOT EXISTS子查询(经典集合包含逻辑)
这是处理“包含所有”类问题最常用的思路,核心是检查不存在S2有但当前供应商没有的零件:
SELECT DISTINCT s.SNO FROM SP s WHERE NOT EXISTS ( -- 先取出S2供应的所有零件 SELECT p.PNO FROM SP p WHERE p.SNO = 'S2' AND NOT EXISTS ( -- 检查当前供应商s是否供应了这个零件 SELECT 1 FROM SP s_p WHERE s_p.SNO = s.SNO AND s_p.PNO = p.PNO ) );
逻辑解释:
- 外层查询遍历每个供应商的记录
- 内层第一个子查询先拿到S2的全部零件列表
- 第二个子查询判断:如果S2的某个零件,当前供应商没有供应,那么这个供应商就会被排除
- 最后用
DISTINCT去重,因为一个供应商可能对应多条零件记录
方法二:使用分组计数(统计匹配的零件数量)
这种方法更直观,通过统计零件数量来判断是否完全覆盖:
-- 先计算S2供应的不同零件总数 WITH s2_parts AS ( SELECT COUNT(DISTINCT PNO) AS total_parts FROM SP WHERE SNO = 'S2' ) SELECT s.SNO FROM SP s JOIN s2_parts ON 1=1 -- 只筛选出供应商供应的、属于S2的零件 WHERE s.PNO IN (SELECT PNO FROM SP WHERE SNO = 'S2') GROUP BY s.SNO, s2_parts.total_parts -- 如果供应商供应的S2零件数量等于S2的总零件数,说明完全覆盖 HAVING COUNT(DISTINCT s.PNO) = s2_parts.total_parts;
逻辑解释:
- 用CTE
s2_parts算出S2的零件总数(示例中是2) - 筛选出所有供应商供应的、属于S2的零件记录
- 按供应商分组后,统计该供应商供应的S2零件数量
- 只有当统计数量等于S2的总零件数时,才说明该供应商覆盖了S2的全部零件
优化提示:
如果你的SP表中(SNO, PNO)是唯一主键(即一个供应商不会重复供应同一个零件),可以去掉DISTINCT,用COUNT(*)代替COUNT(DISTINCT PNO),查询效率会更高。
内容的提问来源于stack exchange,提问作者Israel Obanijesu
相关产品推荐
相关产品推荐

