SQL查询技巧:基于Supplier、Part表检索供应所有零件的供应商
查找供应所有零件的供应商的SQL实现方案
以下方案覆盖三种常见的表设计场景,可按需选择:
场景1:使用中间关联表(行业标准设计,无多值字段)
这是关系型数据库最推荐的设计,单独建立Supplier_Part关联表存储供应关系,核心字段为supplier_id(关联Supplier表主键)、part_id(关联Part表主键)
SELECT s.supplier_id, s.supplier_name FROM Supplier s JOIN Supplier_Part sp ON s.supplier_id = sp.supplier_id GROUP BY s.supplier_id, s.supplier_name HAVING COUNT(DISTINCT sp.part_id) = (SELECT COUNT(*) FROM Part);
逻辑说明:统计每个供应商供应的去重零件数量,数值等于全量零件总数的即为符合要求的供应商。
场景2:Supplier表存在多值字段parts存储供应的零件ID
如果parts为逗号分隔的零件ID字符串,MySQL实现如下:
SELECT s.supplier_id, s.supplier_name FROM Supplier s JOIN Part p ON FIND_IN_SET(p.part_id, s.parts) GROUP BY s.supplier_id, s.supplier_name HAVING COUNT(DISTINCT p.part_id) = (SELECT COUNT(*) FROM Part);
如果使用PostgreSQL且parts为数组类型,实现如下:
SELECT s.supplier_id, s.supplier_name FROM Supplier s JOIN Part p ON p.part_id = ANY(s.parts) GROUP BY s.supplier_id, s.supplier_name HAVING COUNT(DISTINCT p.part_id) = (SELECT COUNT(*) FROM Part);
场景3:Part表存在多值字段suppliers存储可供应的供应商ID
逻辑与场景2对称,反向统计每个供应商覆盖的零件数量,MySQL实现如下:
SELECT s.supplier_id, s.supplier_name FROM Supplier s JOIN Part p ON FIND_IN_SET(s.supplier_id, p.suppliers) GROUP BY s.supplier_id, s.supplier_name HAVING COUNT(DISTINCT p.part_id) = (SELECT COUNT(*) FROM Part);
边界情况兼容:存在零件无任何供应商
如果需要排除「全量零件中存在无供应商的零件,导致没有供应商能满足条件」的特殊场景,可调整统计基数为有供应记录的零件总数:
SELECT s.supplier_id, s.supplier_name FROM Supplier s JOIN Supplier_Part sp ON s.supplier_id = sp.supplier_id GROUP BY s.supplier_id, s.supplier_name HAVING COUNT(DISTINCT sp.part_id) = (SELECT COUNT(DISTINCT part_id) FROM Supplier_Part);
内容的提问来源于stack exchange,提问作者Abdullatif
相关产品推荐
相关产品推荐

