求被多家供应商供应的零件编号的Oracle查询及含义解析
嘿,我来帮你把这个需求讲明白,再给你对应的Oracle查询方案~
需求含义拆解
这个需求的核心很简单:找出所有被至少两个不同供应商供应的零件编号。换句话说,只要某个零件(P_No)在Supp2表中对应了不止一个唯一的供应商编号(S_No),不管这个供应商给这个零件供货多少次,我们都要把这个零件编号筛选出来。
举个例子:如果零件P001有供应商S001和S002都给它供货,那P001就符合要求;但如果只有S001多次给P001供货,那P001就不算。
对应的Oracle查询语句
这里给你三种常用的实现方式,你可以根据实际场景选择:
方法一:GROUP BY + HAVING(最常用、性能最优)
这是处理这类分组统计筛选需求的标准写法:
SELECT P_No FROM Supp2 GROUP BY P_No HAVING COUNT(DISTINCT S_No) >= 2;
解释:
GROUP BY P_No:把Supp2表的数据按零件编号分组,每个组对应一个零件。COUNT(DISTINCT S_No):统计每个零件对应的不同供应商数量(加DISTINCT是为了避免同一个供应商多次供货被重复计数,如果你的业务里Supp2的(S_No, P_No)是唯一的,也可以去掉DISTINCT,写成COUNT(S_No) >= 2)。HAVING:筛选出供应商数量≥2的零件组,最终得到符合要求的零件编号。
方法二:窗口函数实现
如果习惯用窗口函数,也可以这么写:
SELECT DISTINCT P_No FROM ( SELECT P_No, COUNT(DISTINCT S_No) OVER (PARTITION BY P_No) AS supplier_count FROM Supp2 ) t WHERE supplier_count >= 2;
解释:
- 内层子查询用
PARTITION BY P_No按零件分组,用窗口函数统计每个零件的供应商数量。 - 外层查询筛选出供应商数量≥2的记录,并用
DISTINCT去重(因为窗口函数会给每一行都返回统计值,所以需要去重)。
方法三:自连接实现
这种写法逻辑直观,适合理解关联查询的场景:
SELECT DISTINCT s1.P_No FROM Supp2 s1 JOIN Supp2 s2 ON s1.P_No = s2.P_No AND s1.S_No != s2.S_No;
解释:
- 把
Supp2表和自己做连接,匹配同一个零件编号但供应商编号不同的记录。 - 只要能匹配到这样的记录,就说明这个零件有至少两个供应商,最后用
DISTINCT去重得到唯一的零件编号。
小提示
如果你的Supp2表中存在S_No或P_No为NULL的情况,这些记录会被自动排除(因为聚合函数和连接操作都会忽略NULL值),如果需要处理这类特殊情况,可以额外添加WHERE条件过滤或转换NULL值。
内容的提问来源于stack exchange,提问作者iTarunGM
相关产品推荐
相关产品推荐

