• 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=''
    AND EXISTS(SELECT * FROM COURSE WHERE MONTH(CTEST)=7 AND CNO=TEACHER.CNO)
    ORDER BY CNO

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

    类似写法

    补充,今天发现一种方法也可以实现和Exists一样的效果,而且好像这种写法比not exists要快一点,具体的可以自行对比一下。

    例如:查询在商品审核表goods_check已经通过(state=1)的商品,但是在goods表不存在的数据(两个表通过g_id关联)

    1、exists写法:

    select count(*) from goods_check k where k.state=1 and not exists (select * from goods g where g.g_id=k.g_id);

    2、用子查询写法:

    select count(*) from goods_check k where k.state=1 and 
    (
       (select count(*) from goods g where g.g_id=k.g_id) = 0
    );

    首先明确 and 后的子查询的功能和exists类似,为真则返回当前数据,为假则不返回。该子查询的功能是查询goods_check表的g_id在goods表的数量是0的数据。写法1查的是goods_check表的g_id在goods表不存在的数据;

    在goods表不存在 和 在goods表查到的数量=0  是一个概念。因此这两种写法都能实现同样的功能。

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

  • 相关阅读:
    闭包函数 (字符编码,文件处理,函数基础总结)
    函数参数详解
    文件处理及函数基础
    文件处理高级
    面向对象----反射
    正则表达式与re模块
    常用模块
    模块和包
    内置函数与匿名函数
    HDU
  • 原文地址:https://www.cnblogs.com/youreyebows/p/16106440.html
Copyright © 2020-2023  润新知