數(shù)據(jù)庫中表與表相互關(guān)聯(lián)余赢,很多時候要通過查詢多個表才能得到自己想要的數(shù)據(jù)稚叹。
students
courses
reports
在sql server中(不區(qū)分大小寫):
一帐我、連接查詢:通過兩個及以上的表的連接操作來實(shí)現(xiàn)符糊。
1.內(nèi)連接查詢(最常用):只篩選出符合條件的數(shù)據(jù)
from students,reports
where students.sno=reports.sno ;```
```select * from students,reports
where students.sno=reports.sno
and ssex='女';```
where后面的語句是連接條件(即連接謂語)叠洗,連接條件要涉及兩個表中相同屬性的列,and后面是其他限制條件甘改。
'='運(yùn)算符可以換成其他比較運(yùn)算符,使用'='的連接稱作等值連接灭抑,使用其他比較運(yùn)算符的連接稱作非等值連接十艾。
```select students.*,cno,grade
from students,reports
where students.sno=reports.sno;```
沒有重復(fù)的列出現(xiàn)時稱作自然連接,上面的語句把重復(fù)的兩列學(xué)號刪掉一列名挥,連接方式變?yōu)榱俗匀贿B接疟羹。
```select students.sno,sname,cname
from students,reports,courses
where students.sno=reports.sno
and reports.cno=courses.cno;```
多表連接。
```select *
from students,reports
where students.sno=reports.sno
and sdept='自動化'and ssex='女';```
有多個連接條件時稱為復(fù)合條件鏈接禀倔。
```select b.cno,b.cname,a.pre_cno repre
from courses a,courses b
where a.cno=b.pre_cno;```
自身連接查詢救湖,將自己定義兩個別名力九,查詢一門課程的前修課的前修課跌前。
###2.外連接查詢:選出指定表中的所有元組。
```select sname,grade
from students
left join reports
on students.sno=reports.sno;```
左連接:將關(guān)鍵詞left join左邊的表的中的元組全部查詢出來灾炭,即使某些學(xué)生的課程沒有數(shù)據(jù)(填入NULL)
```select sname,grade
from reports
right join students
on students.sno=reports.sno;```
右連接:將關(guān)鍵詞right join右邊的表的中的元組全部查詢出來,即使沒有數(shù)據(jù)(填入NULL)铡原。(左右連接可以相互替代)
```select sname,grade
from reports
full join students
on students.sno=reports.sno;```
全連接:將兩個表中所有的元組全部查詢出來,即使沒有數(shù)據(jù)(填入NULL)
>二燕刻、嵌套查詢:講一個查詢塊嵌套進(jìn)另一個查詢塊的where子句或having短語的條件中的查詢沪哺。
###1.不相關(guān)子查詢:由里向外逐層查詢。子查詢在父查詢之前得到結(jié)果并用作父查詢的查找條件酌儒。
```select sno,grade from
reports
where cno=(select cno
from courses
where cname='數(shù)據(jù)庫');```
返回單值的子查詢,子查詢的結(jié)果和父查詢的條件屬性用比較運(yùn)算符(>,<,=,>=,<=,<>)連接.
```select sname
from students
where sno
in(select sno from reports
where cno='c02');```
```select sname
from students
where sno =any(select sno from reports
where cno='c02');```
返回多值的子查詢枯途,子查詢的結(jié)果和父查詢的條件屬性用in謂詞連接或用ANY和ALL謂詞連接或用集函數(shù)(比較次數(shù)少忌怎,效率高)連接酪夷。
![ANY ALL與集函數(shù)的轉(zhuǎn)換](http://upload-images.jianshu.io/upload_images/2670618-72828f0edf861a97.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###2.相關(guān)子查詢:子查詢依賴于父查詢晚岭,父查詢中的每個元組都帶入到子查詢,符合條件則篩選出來坦报。常用EXISTS與NOT EXISTS謂語库说。
```select sname
from students
where NOT EXISTS (select * from reports
where Sno = Students.Sno AND cno='c01');```
將父查詢中的元組帶入EXISTS與NOT EXISTS謂語后的條件中潜的,若查詢到數(shù)據(jù)則返回ture亡呵,將此條數(shù)據(jù)放入結(jié)果集歇由,查詢不到則返回false,不放入結(jié)果集释牺。所以這兩個謂語的返回結(jié)果并沒有實(shí)際意義,子查詢中的查詢列名也無意義。
有些EXISTS與NOT EXISTS謂語不能被其他形式的子查詢替代虽风,如上述代碼是查找沒有c01這門課的學(xué)生的姓名无牵,特別容易犯如下錯誤:
```select distinct sname
from students,reports
where students.sno=reports.sno
and cno!='c01';```
這樣一個學(xué)生沒選c01但選了其他課程也會被選出來,一門課都沒選的學(xué)生并不會被選出來内舟,所以有些情況不能用連接查詢代替合敦。
##select語句結(jié)果集是元組的集合,所以多個結(jié)果集可以進(jìn)行集合操作验游。
>并操作(union)
```select *
from students
where sdept='計算機(jī)'
union
select * from students
where sage<=20;```
找出計算機(jī)系的或年齡不大于20歲的學(xué)生的所有信息,union 和數(shù)學(xué)中的并一樣充岛,會把默認(rèn)把重復(fù)值刪掉,如果想保留重復(fù)值用union all耕蝉。
>交操作(intersect)
```select *
from students
where sdept='計算機(jī)'
intersect
select *
from students
where sage<=20;```
找出計算機(jī)系的且年齡不超過20歲的學(xué)生的信息崔梗,interscet相當(dāng)于數(shù)學(xué)中的交集,將相同的值篩選出來垒在。
>差操作(except)
```select *
from students
where sdept='計算機(jī)'
except
select *
from students
where sage>20;```
找出計算機(jī)系年齡不大于20的學(xué)生的信息蒜魄,except相當(dāng)于數(shù)學(xué)中的差,當(dāng)然A-B也可以寫成A+(-B),差操作可以由并操作代替场躯。
>對集合查詢結(jié)果排序
```select *
from students
where sdept='計算機(jī)'
union select *
from students
where sage<=20
order by 4 desc,1 asc;```
order by 只能對集合操作的結(jié)果集進(jìn)行排序谈为,所以要寫在最后,根據(jù)第一列和第四列降序排列只需寫出列名踢关。