sql语句里面最难的not exists,exists,口语化解释(个人笔记)

文章目录

  • 1、查询选修了所有课程的学生
  • 2、查询至少选修了课程号为1,2的学生
  • 3、思考一下where是如何筛选记录的
  • 4、exists的返回的是boolean值
  • 5、对查询选修了所有课程的学生的sql进行分解解释
  • 6、其他

初始化点击:建表初始化工作

1、查询选修了所有课程的学生

student为学生表,course为课程表,sc 学生选课表

select Sname
from student
where not exists(
  select *
  from course
  where not exists(
     SELECT *
     from sc
     where Sno=student.Sno AND 
     Cno=course.Cno
  )    
)

2、查询至少选修了课程号为1,2的学生

select Sname
from student
where not exists(
  select *
  from course
  where course.Cno in (1,2) and  not exists(
     SELECT *
     from sc
     where Sno=student.Sno AND 
     Cno=course.Cno
  )    
)

3、思考一下where是如何筛选记录的

写个最简单的sql语句

select
from
where 

执行的过程是 from 选择表格,轮询每条记录,接着来到where,把每条记录去执行where后面的条件语句,当条件返回的为真时,这条记录通过,最后来到select(选择你需要的字段)
所以你甚至可以写 where true(等同于没写where)

4、exists的返回的是boolean值

举个例子,student里面有记录

exists(
select *
from student
where true
)

这时括号里面的sql语句执行完,存在记录。exists返回真

exists(
select *
from student
where false
)

这时括号里面的sql语句执行完,不存在记录。exists返回假

not exists 和 exists恰恰相反

5、对查询选修了所有课程的学生的sql进行分解解释

select Sname
from student
where not exists(
  select *
  from course
  where not exists(
     SELECT *
     from sc
     where Sno=student.Sno AND 
     Cno=course.Cno
  )    
)

我们先假设下:一个学生李勇选修了所有课程,所有课程是7门
整个sql语句执行到李勇的时候,过程是这样的。李勇这条进入第二层嵌套,这时发现 course表有7条记录(因为有7门课),接着李勇先带着course表的第一条记录进入第三层sql语句,下面这条

	 SELECT *
     from sc
     where Sno=student.Sno AND 
     Cno=course.Cno

因为李勇有学第一门课,所以学生选课表,经过where语句,会查询出一条记录。这时第三层的sql语句执行完了,回到第二层嵌套语句的where,经过not exists 返回false,这个时候 course 的第一条记录不会被选择。同样 course 表的第2~7门课都执行结束后,因为李勇都有学,not exists 都会返回false,等同于第二层 course 表记录全部执行完,都不会有一条记录。接着回到第一层sql,not exists 对空记录进行运算,返回一个true,李勇通过。

我们再假设下:一个学生小明选修了5门课程,所有课程是7门,少学了第六门和第七门
整个sql语句执行到小明的时候,过程是这样的。小明这条进入第二层嵌套,这时发现 course表有7条记录(因为有7门课),接着小明先带着course表的第一条记录进入第三层sql语句,因为小明有学第一门课,所以学生选课表,经过where语句,会查询出一条记录。这时第三层的sql语句执行完了,回到第二层嵌套语句的where,经过not exists 返回false,这个时候 course 的第一条记录不会被选择。同样 course 表的第2~5门课都会返回false。但是当执行到第六门课的时候,第三层的sql语句执行完了,没有一条记录(因为小明没有选修第六门课,选课表查不出记录),经过第二层的not exists,返回了一个true,这时候第二层存在了一条记录第六门课,同样第七门课进入第三层,not exists 返回了一个true,到此第二层sql执行结束,存在两条记录,接着来到第一层的 not exists,第二层存在两条记录返回false,所以小明不会被选择。

对比一下小明和小勇,第二层sql执行完的结果,如果都能理解基本就差不多了。

6、其他

6.1 查询选修了所有课程的学生:第二种写法。
思路就是计算出课程数量,再把选课表按照学号分组,再通过having进行等号,就筛选出了选修了所有课程的学生

SELECT DISTINCT student.Sname	#,count(*)
FROM sc	,student
WHERE sc.Sno=student.Sno
GROUP BY sc.Sno
HAVING count(*)=(
SELECT COUNT(*)
FROM course
)

6.2 查询至少选修了课程号为1,2的学生:第二种写法
简单的嵌套查询

SELECT student.Sname
FROM sc,student
WHERE sc.Sno=student.Sno and sc.cno=1 and student.Sno in(
SELECT student.Sno
FROM sc,student
WHERE sc.Sno=student.Sno and sc.cno=2
)

你可能感兴趣的:(日常笔记,数据库,exists,sql)