oracle子查询 in exists

使用子查询(嵌套查询)oop

一、查询有一门及格的学生性能

select * from tbl_student s翻译

     where 60 < any(select score from tbl_grade g where s.snum =g.snum);排序

索引

select * from tbl_student shash

     where 60 < some(select score from tbl_grade g where s.snum = g.snum);for循环

 

any  some  all 区别效率

any表示子查询返回值中的任意一个值(any是等于N个or语句)select

    expr>any(单列多行子查询),expr大于子查询中任一返回值,   也就是只要大于子查询最小返回值就能够了循环

some在此表示知足其中一个的意义,是用or串起来的比较从句。 some和any用法意义是同样的。

all表示子查询返回值中的全部值 (all是等于N个And语句)

    expr>all(单列多行子查询),expr大于子查询中全部返回值,也就是必需要大于子查询中最大返回值才行

 

1  in 子查询

in 按子查询返回值分为:单行单列、多行单列、单行多列、多行多列

     in 按是否与主表链接分为:相关子查询、无关子查询

 

1.1 、单行单列子查询

  查询学生的成绩,要求显示学生的姓名

       select  (select sname from tbl_student s where s.snum=g.snum) as sname,

                   (select cname from tbl_course c where c.cnum=g.cnum) as cname,

                   score

      from tbl_grade g

1.2 、多行单列子查询

       查询男同窗的成绩

       select * from tbl_grade g

        where snum in (select snum from tbl_student where sex=‘0’)

1.3 、单行多列或多行多列子查询

      查询男同窗的成绩

       select * from tbl_grade g   where (snum,’0’) in (select snum,sex from tbl_student)

 

 

1.4 、检索学全了课程的学生

       select * from student s where snum in(

              select g.snum from tbl_grade g group by g.snum

              having count(*) = (select count(*) from tbl_course)

        )

 

 

1.5 、检索没学全课程的学生

     select * from student s where snum in(

              select g.snum from tbl_grade g group by g.snum

              having count(*) < (select count(*) from tbl_course)

        )

 

 

二、exists子查询

只要子查询找到一条记录,结果就是true

 

2.1 、查询选修过课程的学生

   select * from tbl_student s

        where exists (select * from tbl_grade where s.snum=g.snum)

 

2.2 、查询没有选修过 1 号课程的学生的信息

   select *  from tbl_student s

      where not exists

(select * from tbl_grade g where g.cnum=1 and s.snum=g.snum)

 

2.3 、查询男同窗的成绩

   select * from tbl_grade g

      where exists (select * from tbl_student s where s.snum=g.snum and sex=‘0’)

 

 

 

 

2.4 、检索学全了课程的学生

分析:不可能【找不到一门课,这么课找不到成绩】

select s.* from tbl_student s where not exists(

    select * from tbl_course c where not exists(

        select * from tbl_grade g where g.snum=s.snum and c.cnum=g.cnum

    ))

 

2.5 、检索没学全课程的学生

分析:可能【找到  一门课 找不到 成绩】

select s.* from tbl_student s where exists(

    select * from tbl_course c where not exists(

        select * from tbl_grade g where g.snum=s.snum and c.cnum=g.cnum

    ))

 

 

 

in和exists区别

一、 in 是把外表和内表做 hash 链接

        select * from tbl_grade g

     where snum in (select snum from tbl_student where sex=‘0’)

  

    

二、 exists 是对外表做 loop 循环,每次 loop 循环再对内表进行查询。

  如select * from tbl_grade g

           where exists (select * from tbl_student s where s.snum=g.snum and sex=‘0’)

       可理解为:

    for(g : select * from tbl_grade) {

             if(exists(select * from tbl_student s where s.snum=g.snum and sex=‘0’)) {

          print g;

             }

          }

 

所以:

   in:若是内表返回数据量太大,确定生成临时表,并且会进行排序,效率很是低。

         所以,适合内表返回数据量较小的状况。

   exists:外表确定是循环,若是外表数据量太大,也一样效率低。

   所以,适合内表返回数据量多的状况。

 

 

 

使用exists能够按以下思路,不然很差理解:

一、exists子查询是找到即中止并返回true(找到),找不到返回false(找不到)

           说明:不要去翻译为存在和不存在,把脑壳搞晕。

二、头脑中创建for循环

三、exists首先执行外层查询,再执行内层查询,与IN相反。

      若是not in返回至少一个null,那么not in就返回flase,第一个表的数据行就不会显示。    
      对于not exists,只是关心是否返回行,所以返回的不管是null仍是非null,都是true,只要有数据返回。

      使用not in仍是not exists,不单单是功能上不一样,并且在性能上也有很大的不一样。NOT IN会骗过子查询中所涉及表的索引。

相关文章
相关标签/搜索