SQL之对EXISTS谓词的理解

一、首先明确几点:

  1. EXISTS相当于存在量词彐
  2. EXISTS和NOT EXISTS不返回任何数据,只返回逻辑真或者假
  3. 由EXISTS引出的子查询,其目标列表达式通常都用*,因为EXISTS的子查询只返回真值或者假值,不返回选择出来的结果,因此,你给什么样的列名最后返回的都是true或者false,所以给出实际列名无意义。

  • 例1:
SELECT sname
FROM student
WHERE exists
(
SELECT *
  FROM sc
  WHERE sc.sno=student.sno AND cno='1;
)

一、对上面的过程理解:

本查询涉及表student和sc表。

在student表中从头到尾每次取一个元组出来,用这个元组的sno与sc表所有的元组做比较,如果比较条件成立(sc表中存在sno值等于student.sno中值并且其cno='1’的元组),即exists语句中的SQL语句有返回值过来,则EXISTS返回给上一级元组一个true值-----表示允许现在student表中的这个元组可以放入结果表中。

二、注意:

1.首先子查询中必须要有依赖父查询的条件,即我们单独把子查询的select语句提出来不能正常运行。

2.每次查询时父查询表中的一个元组对子查询所有的元组进行判定,如果为true则父查询中的这个元组允许放入结果表,否则进行父查询下一个元组的判定。

  • 例2

    查询选修了所有课的学生姓名

    翻译为:查询这样的学生姓名—不可能没有选course里面的课(因为是双重否定,所以有两个not exists)

    select sname
    from student
    where not exists/*查询的学生不满足这个条件(对sutdent限制)*/select *
        from course
        where not exists/*这个条件就是:没有选Course里面的课(对course限制)*/ 
            (select *
            from sc
            where sno =student.sno
            and cno=course.cno));
    
  • 例3

    扫描二维码关注公众号,回复: 3757421 查看本文章

    查询至少选修了学生201215122选修的全部课程的学生号码

    翻译:不存在这样的课程y,学生201215122选修了y,而学生x没有选

    SELECT DISTINCT Sno
    FROM SC SCX
    WHERE NOT EXISTS/*找的学生号码不满足以下条件*/
    		(SELECT * 
    		FROM SC SCY
    		WHERE SCY.Sno='201215122' AND/*201215122选了的课*/
    				NOT EXISTS(/*这门课在X中没有被选择(不存在)*/
    				SELECT * FROM SC SCZ
    				WHERE SCZ.Sno=SCX.Sno AND
    					  SCZ.Cno=SCY.Cno
    				));
    

猜你喜欢

转载自blog.csdn.net/qq_38338069/article/details/83420792