我在正确的道路上

时间:2014-06-29 19:28:40

标签: oracle

我正在上一个数据库介绍大师班。我们正在研究SQL。教授喜欢对某些解释不明确。

这是我的问题。某些问题我们需要找出与查询相反的问题,例如供应商是否运送红色和蓝色的部件,而不是船舶的颜色。

这是我如何找到解决方案

SELECT distinct PARTS.COLOR
FROM PARTS, SHIPMENTS
WHERE PARTS.COLOR NOT IN(
  SELECT distinct PARTS.COLOR
  FROM SHIPMENTS, PARTS
  WHERE PARTS.PARTNO  IN(
    SELECT distinct SHIPMENTS.PARTNO
    FROM SHIPMENTS
    WHERE SHIPMENTS.SUPPLIERNO='S1'))
AND SHIPMENTS.PARTNO = PARTS.PARTNO;

我想知道的是,这是解决这个问题的最佳方法。这有效,但我不确定应该怎么做。

我还应该提到他不希望我们使用所有可用的操作。他没有告诉我们JOIN,EXISTS,

他向我们展示了SELECT,IN,ALL / ANY,聚合因此MAX,MIN,SUM,GROUP BY和HAVING

由于

2 个答案:

答案 0 :(得分:0)

如果您现在学习使用“EXPLAIN PLAN”查看查询计划,您会发现Oracle经常对“WHERE .. IN()”和“WHERE EXISTS”使用相同的执行计划。根据列上是否有索引,它归结为几个方面,主要是如果您使用统计信息收集,Oracle将查看每个表/索引的行数,并确定哪个是执行它的最佳方法。因此,除非您发现IN()与EXISTS()的运行方式完全不同,否则只需使用当时对您最有意义的那些,但始终检查执行计划。

就您的问题而言,由于您被禁止使用联接或存在,我认为您的解决方案没有任何问题。

我可以提出简单的选项来简化使用连接或存在。你可以用group和outer join来做,但是我认为没有意义。

没有这些限制,我可以简化为:

 SELECT distinct P.COLOR
   FROM PARTS P WHERE NOT EXISTS
     (SELECT 1 FROM SHIPMENTS S WHERE S.PARTNO = P.PARTNO AND S.SUPPLIERNO = 'S1')

虽然我不确定你的架构,以及颜色在哪里。我假设一个部分有一个明显的颜色。如果没有,这是不够的,你需要将子查询与颜色相关联,而不是partno。

答案 1 :(得分:0)

您的问题是:"如果供应商发运红色和蓝色的部件,他们发运的颜色是什么颜色。"

有趣的问题。我认为最简单的方法是使用分析函数,您可能还没有涵盖:

select sp.supplierno, color, count(*)
from (select s.*, p.color
             max(case when p.color = 'red' then 1 else 0 end) over (partition by partno) as HasRed,
             max(case when p.color = 'blue' then 1 else 0 end) over (partition by partno) as HasBlue
      from shipments s join
           parts p
           on s.partno = p.partno
     ) sp
where hasRed > 0 and hasBlue > 0
group by sp.supplierno, color;