带有EXISTS的相关子查询

简介

  • 不相关子查询:子查询的查询条件不依赖于父查询的称为不相关子查询。
  • 相关子查询:子查询的查询条件依赖于外层父查询的某个属性值的称为相关子查询(Correlated Subquery),带EXISTS 的子查询就是相关子查询
  • EXISTS表示存在量词:带有EXISTS的子查询不返回任何记录的数据,只返回逻辑值 ‘ True ’ 或 ‘ False ’

表结构

SC:选课表,某个学生选了某门课

Cno:课程编号; Sno:学号

student:学生表

Sname:姓名; Sno:学号

Course:课程表

Cno:课程编号

例1:求所有选修了‘C1’课程的学生名。

不相关子查询:

SELECT Sname 
FROM student 
WHERE Sno IN (SELECT Sno FROM SC WHERE Cno = 'C1'); 

相关子查询:

SELECT Sname
FROM student
WHERE EXISTS    
(
    SELECT * 
    FROM SC
    WHERE student.Sno=SC.Sno AND Cno='C1' 
);

相关子查询执行过程:

先在外层查询中取student表的第一个元组(记录),用该记录的相关的属性值(在内层WHERE子句中给定的)处理内层查询,若外层的WHERE子句返回‘TRUE’值,则此元组送入结果的表中。然后再取下一个元组;重复上述过程直到外层表的记录全部遍历一次为止。

不关心子查询的具体内容,因此用 SELECT *, Exists + 子查询用来判断该子查询是否返回元组。 Exists:当子查询的结果集非空时,返回为‘True’;当子查询的结果集为空时,Exists为‘False’ 。 NOT EXISTS :若子查询结果为空,返回‘TRUE’值, 否则返回 ‘FALSE。

例2:列出没有选C1课程的学生的学号、姓名

SELECT Sname
FROM student
WHERE NOT EXISTS
(
    SELECT *
    FROM SC
    WHERE student.Sno = SC.Sno AND Cno = 'C1'
);

例3:查询选修了所有课程的学生的姓名(续)

SELECT Sname
FROM student
WHERE NOT EXISTS
(
    SELECT *
    FROM Course
    WHERE NOT EXISTS
    (
       SELECT *
       FROM SC
       WHERE student.sno=SC.sno AND Course.Cno=SC.Cno
    )
);

例4:查询至少选修了S1所选的全部课程的学生名

SELECT Sname
FROM student
WHERE NOT EXISTS                     
( 
    SELECT *
    FROM SC AS SCX            
    WHERE SCX.Sno='s1' AND NOT EXISTS            
    (
        SELECT *
        FROM SC AS SCY
        WHERE  student.Sno=SCY.Sno AND SCX.Cno=SCY.Cno
    )
);

在FROM语句中使用子查询,对查询结果定义表名及列名 例:求平均成绩超过80分的学号及平均成绩

SELECT Sno, AVG_G
FROM        
(
    SELECT Sno,AVG(Grade)
    FROM SC
    GROUP BY Sno 
) AS RA(Sno, AVG_G)
WHERE AVG_G > 80 

你可能感兴趣的:(exists)