SQL中exists的用法实战记录


首先注意拼写(因为我老是记错字母顺序或者位数)exists,是6个字母;发音:[?ɡ?z?sts],原型:exist;

举例

下面直接进入正题,先上个例子

select * from user u where u.age<25 and EXISTS (
select * from grade g where g.g_name=u.name )

含义:查询user表年龄小于25岁,并且在grade表存在的用户;通过g.g_name=u.name关联;

以下几个小圆点可以帮助理解上述SQL的查询过程

  • 查询user表第一条数据,age是小于25的,name=Jone,这时去grade表查g_name=Jone是否有数据,有数据,则返回user表第一条数据;
  • 查询user表第二条数据,age不满足小于25,不查出user表第二条数据;
  • 查询user表第三条数据,age是小于25的,name=Jack,这时去grade表查g_name=Jack是否有数据,无数据,不查出user表第三条数据;
  • ......

上述SQL用IN来实现,结果是一样的

select * from user u where u.age<25 and u.name in (select g_name from grade);

查询过程:

  • DBMS首先处理最里面的子查询。系统首先执行“select g_name from grade”语句,生成grade表中所有用户的g_name集;
  • 然后DBMS一次处理user表中的一行记录,并且将每行记录中的name列值与子查询结果集中的SNO值进行比较;
  • 如果子查询中能找到正在处理的name值,where子句求值为True,DBMS则将该记录的相关信息归入结果表。如果未找到,则DBMS转而去处理user表中下一行而舍弃该行数据;
  • ......

至于exists和in的区别,我现在是想到哪个用哪个,没有专门研究过,网上文章很多,大家可以去搜索一下~

查阅资料后的总结

简单的EXISTS查询语句表示如下:

SELECT column_name
FROM table_name
WHERE [NOT] EXISTS (subquery)

只要子查询subquery中能查询出数据,EXISTS(subquery)返回True,则外层查询的WHERE子句的结果也为True,则返回外层查询的这条数据。否则,就不返回外层查询的这条数据。

 注意点:

1、需要注意EXISTS前可以加NOT,用于否定:

2、子查询subquery中查询的字段不重要,怎么写都对,无论是SELECT * 还是SELECT column_name ,该子查询返回的结果要么是True,要么是False(既不会返回*,也不会返回具体列值)

 课后练习

1、在COURESE表中查询在STUDENT表中未被选修的课程的课程号、课程名称、学时和考试时间信息;

SELECT CNO,CNAME,CTIME,CTEST
FROM COURSE AS C
WHERE NOT EXISTS(SELECT * FROM STUDENT WHERE CNO=C.CNO)

2、在Teacher表中查询女教师开设的、7月份考试的课程号、开课教师的姓名以及教师所在的系;

分析:

(1)首先明确我们要查的是Tacher表的数据:CNO、TNAME、DNAME;

(2)但要查的不是Tacher表所有数据,是有条件的。

  • 条件一:TEACHER.TSEX='女'
  • 条件二:MONTH(COURSE.CTEST)=7
  • TEACHER表和COURSE表如何关联呢?TEACHER.CNO=COURSE.CNO

(3)想一想,在TEACHER表已经查出了女教师的信息及所教的课程号,在COURSE表也查出了7月考试的课程号。如果TEACHER表女教师所教的课程号在COURSE表存在且其考试月份是在7月,那就是我们要查的数据啦,实际我们要查询的是Teacher表中女老师开设的课程和Course表中7月考试的课程的交集。

SELECT CNO,TNAME,DNAME
FROM TEACHER
WHERE TSEX=''
ANX EXISTS(SELECT * FROM COURSE WHERE MONTH(CTEST)=7 AND CNO=TEACHER.CNO)
ORDER BY CNO

最后,本人简单粗暴的一句话总结(大家可以忽略):exists就是查询A表中满足条件并且在子查询B表中存在的数据

参考书籍:《SQL查询的艺术》(张权,郭天娇)