首页 > 代码库 > SQL 中 EXISTS 与 NOT EXISTS
SQL 中 EXISTS 与 NOT EXISTS
带有 EXISTS 操作符的子查询不返回任何数据,只产生逻辑真值 ‘true‘ 或逻辑假值 ‘false‘。带有 EXISTS 操作符的子查询都是相关子查询。
相关子查询:子查询的条件依赖父查询。
EXISTS:如果内层查询结果非空,则外层 WHERE 子句返回真值,输出外层查询结果。
NOT EXISTS:如果内层查询结果为空,则外层 WHERE 子句返回真值,输出外层查询结果。
样例表
CREATE TABLE Student (Sno CHAR(9) PRIMARY KEY, --学号 Sname CHAR(20) UNIQUE, --姓名 ); create table SC (sno char(9), --学号 cno char(4), --课程号 primary key (sno,cno), foreign key (sno) references student(sno) );
/*查询至少有一门课没选的学生姓名*/ SELECT sname FROM Student WHERE EXISTS (SELECT * FROM Course WHERE NOT EXISTS(SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)); -- 外层要有查询结果 中层查询结果要为非空 内层查询结果要为空 = 至少有一门课没选 /*查询所有课都没选的学生姓名*/ SELECT sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)); --外层要有查询结果 中层查询结果要为空 内层查询结果要为空 = 所有的课都没选 /*查询至少选了一门课的学生姓名*/ SELECT sname FROM Student WHERE EXISTS (SELECT * FROM Course WHERE EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)); --外层要有查询结果 中层查询结果要为非空 内层查询结果要为非空 = 选了至少一门课 /*查询选了所有课的学生姓名*/ SELECT sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS(SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)); --外层要有查询结果 中层查询结果要为空 内层查询结果要为非空 = 选了所有的课 /*用 GROUP BY */ SELECT sname FROM Student LEFT JOIN SC ON Student.Sno=SC.sno GROUP BY Sname HAVING COUNT(cno)<= (SELECT COUNT(cno) FROM Course)-1; SELECT sname FROM Student LEFT JOIN SC ON Student.Sno=SC.sno GROUP BY Sname HAVING COUNT(cno)= 0; SELECT sname FROM Student LEFT JOIN SC ON Student.Sno=SC.sno GROUP BY Sname HAVING COUNT(cno)>= 1; SELECT sname FROM Student LEFT JOIN SC ON Student.Sno=SC.sno GROUP BY Sname HAVING COUNT(cno)= (SELECT COUNT(cno) FROM Course);
/*查询至少选修了学生 201215122 选修的全部课程*/ SELECT DISTINCT sno FROM SC x WHERE NOT EXISTS (SELECT * FROM SC Y WHERE Y.sno=201215122 AND NOT EXISTS(SELECT * FROM SC Z WHERE Z.sno=X.sno AND Z.cno=Y.cno)); --外层要有查询结果 中层查询结果要为空 内层查询结果要为非空 = 至少选修了201215122 选修的全部课程 SELECT cno INTO copy FROM SC WHERE sno=201215122; --复制 201215122 选的课号到 copy 表 SELECT DISTINCT sno FROM copy LEFT OUTER JOIN SC ON SC.cno=copy.cno --以 copy 表为全部行 GROUP BY sno HAVING COUNT(SC.cno)= (SELECT COUNT(cno) --排序只选了 copy 表中的一门或几门课的 sno FROM copy);
SQL 中 EXISTS 与 NOT EXISTS
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。