带有ALL或ANY谓词的子查询
ALL:所有值
ANY:某个值
EXISTS代表存在量词,带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真“TRUE”或逻辑假“FALSE”。
例子:查询所有选修了1号课程的学生姓名
SELECT same FROM student WHERE EXISTS (SELECT * FROM SC WHERE sno=studet.sno AND cno='1') |
若内部查询结果为非空,则返回TRUE,反之返回FALSE
与EXISTS相对应的是NOT EXISTS,若内部查询结果为空,则返回TRUE,反之返回FALSE
例子:查询没有选修课程1的学生姓名
SELECT sname FROM student WHERE NOT EXISTS (SELECT * FROM SC WHERE sno=student.sno AND con='1') |
进阶版:
例子1:查询选修了全部课程的学生姓名
MySQL中没有全称量词,转化该例子,查询“没有一门课没选的学生姓名”,该句子中有两个没,因此有两个NOT EXISTS,一个是课,一个是选。先有课才有选,所以第一个NOT EXISTS对应的是课,
SELECT sname FROM student WHERE NOT EXISTS (SELECT * FROM course [……]) |
第二个NOT EXISTS对应的是选,学生选的课
SELECT sname FROM student WHERE NOT EXISTS (SELECT * FROM course WHERE NOT EXISTS (SELECT * FROM SC WHERE SC.sno=student.sno AND SC.cno=course.cno)); |
例子2:查询至少选修了学生201215122选修的全部课程的学生号码
又是一个全部的问题,同样需要改写,“查询学生201215122选修的课程没有一门没有选修的学生号码”,也是两个没,所以是两个NOT EXISTS。
第一步:搭框架
SELECT sno FROM student WHERE |
第二步:课,学生201215122选修的课
SELECT cno FROM SC WHERE SC.sno=201215122 |
加入原框架
SELECT sno FROM student WHERE NOT EXISTS ( SELECT cno FROM SC WHERE SC.sno=201215122 ) |
第三步:选,要输出的学生所选的课,出现第二个NOT EXISTS
SELECT sno FROM student WHERE NOT EXISTS ( SELECT cno FROM SC a WHERE a.sno=201215122 AND NOT EXISTS (SELECT * FROM SC b WHERE b.sno=student.sno AND b.con=a.sno) ); |