找出没有使用天津产的零件的工程号码

建表语句:https://blog.csdn.net/karive/article/details/105055038

常见写法:

SELECT DISTINCT JNO 
FROM SPJ,S 
WHERE S.SNO=SPJ.SNO AND S.CITY<>'天津'

SELECT    DISTINCT JNO 
FROM    J
WHERE    JNO NOT IN(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

SELECT    DISTINCT JNO
FROM    SPJ
WHERE    JNO NOT IN(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

SELECT    DISTINCT JNO
FROM    J
WHERE    NOT EXISTS(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    AND J.JNO=SPJ.JNO);

SELECT    DISTINCT JNO
FROM    SPJ
WHERE    NOT EXISTS(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

执行结果:(SQL Server 2019)

结果分析:

第一种方法:错。

SELECT DISTINCT JNO 
FROM SPJ,S 
WHERE S.SNO=SPJ.SNO AND S.CITY<>'天津'

原因在于,如果同一个工程同时使用了“天津的零件”和“不是天津的零件”的,也会在结果中。但是,根据语义,只要使用了“天津的零件”,就不能在结果中。因此,方法一是错误的。


 第二种方法:对。

SELECT    DISTINCT JNO 
FROM    J
WHERE    JNO NOT IN(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

第三种方法:错。

SELECT    DISTINCT JNO
FROM    SPJ
WHERE    JNO NOT IN(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

跟第二种方法比较,From来自于SPJ而不是J,这样的话,J表中的部分数据会丢失。


 第四种方法:对。

SELECT    DISTINCT JNO
FROM    J
WHERE    NOT EXISTS(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    AND J.JNO=SPJ.JNO);

第五种方法:错。 

SELECT  DISTINCT JNO
FROM    SPJ
WHERE   NOT EXISTS(SELECT JNO
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

错误的原因:不相关子查询。内层只要有结果(不为空),那么,NOT EXISTS 之后,最终结果就全部为空。

如果觉得不好理解,可以吧NOT EXISTS换为EXISTS试一下:

SELECT  DISTINCT JNO
FROM    SPJ
WHERE   EXISTS(SELECT *
                     FROM S,SPJ
                     WHERE CITY='天津'AND S.SNO=SPJ.SNO    );

结果如下:

为什么是所有SPJ中的JNO? 原因在于,内层结果为真,所以显示全部数据。

这种写法,只看内层的结果是否有天津供应的零件:SPJ所有的元组中,有1个或者多个天津供应的零件,就是真;SPJ所有的元组中,完全不存在(0个)天津供应的零件,就是假。

这与题目是不相符的,所以是错误的。

原文地址:https://www.cnblogs.com/hbuwyg/p/14903682.html