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會騙過子查詢中所涉及表的索引。

相關文章
相關標籤/搜索