先選擇一個數據庫
use jobtest
go
引入:該數據庫jobtest裏面有兩張表,Student學生表和Grade年級表,表中的數據如下所示:
學生表Student:
年級Grade表:
接下來我們來看看sql server中的子查詢:
子查詢
1.查詢編號比李太白大的學生信息
--先獲取李太白的編號
declare @sid int ;
select @sid = sid from student where sname = '李太白'
--再查詢編號比@sid大的信息
select * from student where sid>@sid
當然我們也可以改成子查詢:
—可以改成子查詢(將@sid替換成獲取李太白編號的sql語句)
select * from student where sid>(select sid from student where sname = '李太白')
其運行結果都是:
以上就是一個最簡單的子查詢。
習慣上,外面的查詢稱爲父查詢,括號裏面的則是子查詢,返回結果集。因爲子查詢作爲where條件的一部分,所以還可以和update、insert以及delete一起使用,語法和select的類似。
注意:將子查詢和比較運算符聯合使用,必須保證子查詢返回的值不多於一個。
還有一個就是:
select * from student不如select sid,sname,sphone,spass,sgid from student的效率高,可維護性也比不上,所以一般使用後者。
下面我們再來一個子查詢的案例
需求:查詢青鳥一班的學生信息
我們可以看到思路是這樣的:
(1)先根據年級名稱查詢出年級編號
(2)學生表裏面的年級編號讓和查詢出來的年級編號對應起來就可以了
select * from student where sgid = (select gid from grade where gname = '青鳥一班')
運行結果:
in和not in查詢
前面我們說過,將子查詢和比較運算符聯合使用,必須保證子查詢返回的值不多於一個。
如果返回多個值的話會怎麼樣呢?我們不妨來試試、
查詢學生表中,年級編號是1的年級名稱
select gname from grade where gid =(select sgid from student where sgid = 1)
運行結果:
可見,程序給我報異常了,表示子查詢返回了多個結果。
正確寫法應該是這樣的:
select gname from grade where gid in(select sgid from student where sgid = 1)
in子查詢適合用在子查詢結果集返回多條記錄的情況下。
反過來not in就是正好與in取反,還是同樣上面給出的例子,我們換成not in看看結果是什麼樣的?
select gname from grade where gid not in(select sgid from student where sgid = 1)
結果:
很明顯,除了青鳥一班,其餘年級名稱均已輸出。
exists和no exists
exists,只注重子查詢是否有返回行,如查有返回行結果爲真,否則爲假,並不適用子查詢的結果,僅使用測試子查詢是否有返回結果
下面來舉例說明一下:
查詢是否有編號爲6的學生信息,如果有,則輸出‘有編號是6的學生’
if exists(select * from student where sid = 6)
print '有編號是6的學生'
運行結果爲:
因爲表中並沒有編號是6的學生信息。
而not exists正好與exists相反,還是利用上面的案例
if not exists(select * from student where sid = 6)
print '有編號是6的學生'
運行結果爲: