日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Oracle数据库的嵌套查询

發布時間:2023/12/14 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle数据库的嵌套查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

備注:此博客為轉載,方便自己學習 Oracle的嵌套查詢,原作者地址請點擊此處

在前面2個章節,我們比較詳細的介紹了一些SQL語句的基本用法,但是在我們實際的項目開發中,其實很多時候這些基本的用法遠遠不能滿足我們項目的需求,這個時候就需要我們的嵌套查詢。

在SQL語句中,一個select-from-where語句稱為一耳光查詢快。將一個查詢快嵌套在另外一個的where子句或having 短語的條件的查詢稱為嵌套查詢(Nested Query)。

比如,先舉一個簡單的例子:

select Sname --------------外查詢語句塊------- from Student where Sno in --------------外查詢語句塊------- ( --------------內查詢語句塊------- select SnoFrom Scwhere Cno=2--------------內查詢語句塊------- );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

查詢語句塊分為外查詢語句或叫父查詢以及內查詢或子查詢。

NOTE:SQL語言允許多層嵌套查詢,即一個子查詢中還可以嵌套其他子查詢。需要特別指出的是,子查詢的select語句中不能使用order by字句,order by 只能對最終查詢結果排序。

一。帶有in謂詞的子查詢

在嵌套查詢中,子查詢往往是一個集合,所以謂詞in是嵌套查詢中最經常使用的謂詞。

【例1】查詢與“XiaoHong”在同一個系的學生

OK,我們一步一步的來分解這個查詢步驟:

①確定“XiaoHong”所在的系

select sdept from student where sname='XiaoHong'
  • 1
  • 2
  • 3

得到的結果是:CS。

②查找所有在CS系學習的所有學生

select sno,sname,sdept from student where sdept='CS';
  • 1
  • 2
  • 3

ok,得到如下結果:

③合并操作。

現在我們只需要把上面的操作合并在一起就好了!

select sno,sname,sdept from student where sdept in (select sdeptfrom student where sname='XiaoHong' );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

得到的結果也是一樣。

本例中,因為子查詢的查詢條件不依賴于父查詢,所以稱為不相關查詢。

當然本例中也還可以有其他解法:自連接方法如下:

select s1.sno,s1.sname,s1.sdept from student s1,student s2 where s1.sdept=s2.sdept and s2.sname='XiaoHong';
  • 1
  • 2
  • 3

可見,一個查詢有很多種方法,當然不同的方法執行的效率可能會有很大的不同。

【例2】查詢選修了課程名為”Math“的學生學號和姓名

看似這一句很短,其實這里有2個子查詢。我們需要先弄清楚里面的關系,然后在來進行解答

思路如下:

1).課程名在course表中才有,所以我們從course表中選出課程名為Math的課程號(Cno)

2).選出課程號之后,在在SC表中,找到課程號所對應的學生號

3).在student表中找出對應的學號和學生名字。

select sno,sname --第三步,最后從student表中取出數據出來。 from student where sno in (select sno --第二步。。找出SC關系表中的選修了2號課程的學生學號 from sc where cno in(select cno -- 第一步。。找出course表中的課程名為math的課程號。結果為2.from course where cname='Math') );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

結果如下:

代替方法:

select student.sno,sname from student,sc,course where course.cname='Math' and course.cno=sc.cno and sc.sno=student.sno;
  • 1
  • 2
  • 3
  • 4

結果也是一樣滴。

二。帶有比較運算符的子查詢

帶有比較運算符的子查詢是指父查詢之間用比較運算符進行連接。當用戶能確切知道內存查詢返回的是單值時,可以用>,<,>=,<=,!=,<>等等比較運算符。

【例3】和例1 是一樣的:查詢與“XiaoHong”在同一個系的學生

因為一個學生只可能在一個系學習,也就是說內查詢的結果是一個值,因此可以用“=”代替“in”

如下:

select sno,sname,sdept from student where sdept = (select sdeptfrom student where sname='XiaoHong' );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這樣 也能得到和例1的結果。

需要注意的是,子查詢一定要跟在比較符之后,下面寫法是錯誤的:

----------------錯誤寫法--------------------- select sno,sname,sdept from student where (select sdeptfrom student where sname='XiaoHong') =sdept; ----------------錯誤寫法---------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

【例4】找出每個學生超過他選修課課程平均成績的課程號

這個怎么理解呢?我們先把結果寫出來,然后再來剖析它。

select sno,cno from sc x where grade>= (select avg(grade) from sc y where y.sno=x.sno);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

x是Sc表的別名,y也是一樣。內存查詢是求一個學生所有選修課程平均成績,至于是哪個學生的平均成績要看s.sno的值。,而該值是和父查詢有關的,所以這類查詢叫做相關子查詢。

執行過程可能如下:

①從外層查詢中取出SC表中的一行(也就是元組 x),將x的值sno

select avg(Grade) from sc y where y.sno=1;
  • 1
  • 2
  • 3

得到結果是98.5

②執行內查詢得到的結果是:98.5,所以得到外查詢是:

select sno,cno from sc x where Grade>=98.5;
  • 1
  • 2
  • 3

得到結果如下:

然后,外層查詢取出下一個元組重復做上面的動作。。。

得到的結果是:

三。帶有any(some)或all謂詞的子查詢
子查詢返回單值可以用比較算術法,但是返回多值時要用any(有些系統用some)或者all謂詞修飾符。而是用any或all謂詞時則必須同時是用比較運算符。

any 大于子查詢結果中的某個值

select sname,sage from student where sage < any (select sage from student where sdept='CS' ) and sdept <> 'CS'; -- 注意這是父查詢的條件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

數據庫執行執行此查詢的時候,首先處理子查詢,找出CS系中所有學生的年齡,找出一個集合(18,22)。任何處理父查詢,找出所有不是CS系并且年齡小于18或22的學生即可。

本查詢也可以用聚集函數來實現。首先用子查詢查出CS系中最大年齡(22),任何在父查詢中找出所有非CS系并且年齡小于22歲的學生即可。

select sname,sage from student where sage < (select max(sage)from studentwhere sdept='CS' ) and sdept<>'CS'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

也可以得到上面的結構。結果如下:

【例6】查詢其他系中比計算機科學系所有學生年齡都小的學生姓名和年齡

經過上面的分析,這個很簡單,如下

select sname,sage from student where sage <all (select sagefrom studentwhere sdept='CS' ) and sdept<> 'CS';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這里需要向大家說聲對不起,剛開始構建數據的時候,沒有構建好,所以這里查詢為空,為了試驗的完整性,我這里修改一下數據結構。

update student set sage=17 where sname='XiaoZhang';
  • 1

ok,我們現在在執行剛才的操作,可以得到如下結果。

本查詢也可以使用聚集查詢來實現,如下:

select sname,sage from student where sage < (select min(sage)from studentwhere sdept='CS' ) and Sdept !='CS';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

事實上,聚集函數實現子查詢通常比直接用all或any的效率更好。對應關系表如下:

四。帶有exists謂詞的子查詢
帶有exists謂詞的子查詢不返回任何數據,只產生邏輯真或假,也就是true或false。

【例6】查詢所有選修了1號課程的學生姓名

select sname from student where exists (select *from scwhere Sno=Student.Sno and Cno=1 )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

那上面的執行流程是怎么樣的呢?

①從外查詢student表中取出一行數據

②把這條數據的Sno和內查詢Sc表中的Sno進行比較

③若比較結果為真,則把這數據的sname放入一個結果集合中。

④然后再取student表的嚇一條數據,直到取完為止。

使用exists量詞后,若內存結果非空,則外層的where字句返回真值,否則返回假值。

由于exists引出的子查詢,起目標列表達式通常都是“*”,因為帶有exists的子查詢只返回true或false,給出列名無具體意思。

exists謂詞相對應的是not exists。使用not exists后,如果內存查詢結果為空,則外層的where字句返回真值,否則返回假值。

【例7】查詢沒有選修了1號課程的學生姓名

select sname from student where not exists (select *from scwhere Sno=Student.Sno and Cno=1 )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

一些帶exists或not exists謂詞的子查詢不能被其他形式的子查詢等價替換,但是其他帶有in謂詞、比較運算符、any、all謂詞的子查詢都能用exists謂詞的子查詢替換。

總結

以上是生活随笔為你收集整理的Oracle数据库的嵌套查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。