SQL的NOT EXISTS双重否定

平时接触的少,写个文章做笔记。

有关系模式如下:

教师关系 T(T#,TNAME,TITLE)

课程关系 C(C#,CNAME,T#)

学生关系 S(S#,SNAME,AGE,SEX)

选课关系 SC(S#,C#,SCORE)

题目:检索全部同学都选修的课程的课程号和课程名

SQL:

SELECT DISTINCT C#,CNAME
FROM C 
WHERE NOT EXISTS (SELECT *
                  FROM S
                  WHERE NOT EXISTS(SELECT *
                                   FROM SC
                                   WHERE SC.S#=S.S# AND SC.C#=C.C#) );

解析:

SQL语句的 WHERE (NOT) EXISTS (……)的运行逻辑是:先执行外部查询,然后遍历外部查询的每一个元组(行),将外部查询结果用于内部查询。这点与WHERE ... (NOT) IN 有所不同。

因此在本题的SQL中,其实际含义为:

查询课程表C,然后查询学生表S,执行笛卡尔积(每一个课程表的元组会和每一个学生表的元组进行组合,产生一个 n*m 行的新表),然后所得结果的每个元组执行最里层的查询:如果课程和学生的组合能在选课表SC中找到(即符合题设要求的全部同学都选修的课程),则返回False给中间层的子查询,表示这个查询不符合NOT EXISTS要求。那么在中间层中,从最里层返回False的学生数据就会被改为不存在,这就又是符合最外层NOT EXISTS要求的,会继而返回True给最外层查询,那么这个符合题设要求的数据就经历两次否定最终被找到了。

注意:NOT EXISTS 符合要求返回False,不符合要求返回True

你可能感兴趣的:(sql,数据库)