SQL查询语句中EXISTS和 NOT EXISTS的用法
针对于:解决SQL语句查询选修全部课程,销售所有商品,使用所有零件类问题
首先我们要明白EXISTS的作用
EXISTS运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。NOT EXISTS的作用相反 用于判断查询子句是否有记录,如果有则返回False,否则返回Ture。
范例:
Select *
from 表名
where EXISTS (比较对象)
”比较对象“由另外一个查询语句构成。
WHERE EXISTS (比较对象)如果返回值为真,输出这个元组,返回值为假 跳过比较下一个。
WHERE NOT EXISTS (比较对象)如果返回值为真,输出这个元组,返回值为假 跳过比较下一个。
例题1. 现有关系模式如下
学生S(Sno, Name,Dept,Age),
课程C(Cno, Cname),
学生选课SC(Sno,Cno,Grade)。
求选修了全部课程的学生学号、姓名及其所在系名。
解析:求选修了全部课程的学生学号,那么对于这类学生来说不存在(或没有)这种情况:课程表C中某一门课程不存在于这类学生的选课表SC中
双重否定表肯定。输出元组。 没有一门课程不存在于这个学生的选课表中
然后我们根据解析从后向前写SQL语句
(1)首先某一门课程不存在学生的选课表中
/*判断是否有一门课程没有选*/
SELECT *
FROM C
WHERE NOT EXISTS ( /*如果存在返回FALSE 不输出这个元组*/
SELECT *
FROM SC
WHERE SC.Cno=C.Cno) /*SC.Con = C.Con 起等值连接作用不可省略*/
(2)判断每个学生是否存在有一门课程没有选
SELECT Sno, Name, Dept
FROM S
WHERE NOT EXISTS (/*判断学生是否有存在这种情况 属于则返回FALSE,否则返回TRUE*/
SELECT *
FROM C
WHERE NOT EXISTS ( /*否有一门课程这个学生没有选 若没有选,则返回FALSE,否则返回TRUE*/
SELECT *
FROM SC
WHERE SC.Cno=C.Cno AND SC.Sno=S.Sno/*起等值连接作用,限制学生表S中的每个元组每次比较的对象*/
)
)
Where Y.Cno=X.Cno# AND Y.Sno=S.Sno的作用在于限制最外层查询中每个元组每次比较的对象,两个NOT EXISTS 都为FALSE的话。
例2 关系模式如下:
商品P(PNO, PN, COLOR, PRICE)
商店S(SNO, SN, CITY)
销售SP(PNO, SNO, QTY)
(1)用SQL语言分别写出查询语句,查询销售所有商品的商店名SN。
双重否定表肯定。输出元组。
没有一个产品不被这个商店销售
SELECT SN
FROM S
WHERE NOT EXISTS (/*判断这个商店是否存在这种情况 属于则返回FALSE,否则返回TRUE*/
SELECT *
FROM P
WHERE NOT EXISTS (/*判断是否至少有一个产品这个商店不销售 若不销售则返回FALSE,否则返回TRUE*/
SELECT *
FROM SP
WHERE S.SNO = SP.SNO AND SP.PNO = P.PNO
)
)
(2)用关系代数及SQL语言分别写出查询语句,查询不销售商品P2(商品号)的商店名SN。
SELECT SN
FROM S
WHERE NOT EXISTS(/*判断这个商店是否属于这种情况,属于则返回FALSE,否则返回TRUE*/
SELECT *
FROM SP
WHERE PNO = 'P2' AND SNO = S.SNO
)
若有不正确的地方,欢迎指正