楊浩宇
(昆明工業(yè)職業(yè)技術(shù)學(xué)院,云南 昆明 650302)
數(shù)據(jù)查詢作為數(shù)據(jù)庫操作的重點(diǎn),也一直是學(xué)習(xí)者的學(xué)習(xí)重點(diǎn),多表查詢則是其中不可回避的重點(diǎn)與難點(diǎn)。本文以一個(gè)學(xué)生數(shù)據(jù)庫(Student)為例討論幾種實(shí)現(xiàn)多表查詢的方式。
Studen中有三張表:stuinfo(學(xué)生信息表),用于存放學(xué)生基本信息;course(課程信息表),用于存放課程信息;score(成績表)用于存放學(xué)生各課程的考試成績,具體結(jié)構(gòu)如下:
表1 學(xué)生信息表結(jié)構(gòu)
表2 課程信息表結(jié)構(gòu)
表3 成績表結(jié)構(gòu)
對于這三張表的多表查詢主要集中在成績的統(tǒng)計(jì)和查詢上。
例如,查詢學(xué)生每門課程的成績,包括學(xué)號(hào)、姓名、課程名稱和成績信息,用SQL語句完成如下:
select d1.stuid,d1.name,d2.cid,d2.cname,d3.score
from stuinfo d1,course d2,score d3
where d1.stuid=d3.stuid and d2.cid=d3.cid
或者,查詢每位學(xué)生所學(xué)課程的平均分,包括學(xué)號(hào)、姓名和平均分:
select d2.stuid,d2.name,AVG(d1.score)
from score d1,stuinfo d2
where d1.stuid=d2.stuid
group by d2.stuid,d2.name order byAVG(d1.score)desc
再如,統(tǒng)計(jì)各門課程的最高分、最低分和平均分:
select d2.cid,d2.cname,AVG(d1.score),MAX(d1.score),MIN(d1.score)
from score d1,course d2
where d1.cid=d2.cid
在SQL Server8中除了用SQL語句完成這類問題,也可以用其它的數(shù)據(jù)庫對象完成。以學(xué)生所學(xué)課程成績查詢?yōu)槔?,用如下語句建立一個(gè)叫做score1的視圖,然后查看score1的數(shù)據(jù)來查看到位學(xué)生的各門課程成績,而且,還可以再通過SQL語句對score1行和列進(jìn)行選擇統(tǒng)計(jì)數(shù)據(jù)。
create view score1
as
select d1.stuid,d1.name,d2.cid,d2.cname,d3.score
from stuinfo d1,course d2,score d3
where d1.stuid=d3.stuid and d2.cid=d3.cid
例如,查詢每位學(xué)生學(xué)過的所有課程的平均分,對視圖score1操作的SQL語句:
Select stuid,name,avg(score)from score1 group by stuid,name
圖1 視圖統(tǒng)計(jì)學(xué)生各科平均分
查詢各門課程的最高分、最低分和平均分,通過對Score1視圖的操作來完成SQL語句如下:select cid,cname,max(score),min(score),avg(score)from score1 group by cid,cname
可見,對比之前對多表查詢的語句,視圖查詢簡潔很多。
圖2 視圖查詢結(jié)果
視圖作為數(shù)據(jù)庫中的一種對象,是一個(gè)虛擬表,視圖一旦被建立,作用與表相同,但它并不保存任何數(shù)據(jù),它的數(shù)據(jù)來自定義視圖的查詢所引用的表。視圖可以使用戶將焦點(diǎn)集中于感興趣的數(shù)據(jù),不必要的數(shù)據(jù)可以不出現(xiàn)在視圖中,這也增加了數(shù)據(jù)的安全性;其次,視圖可以減化操作,特別是對于對多表查詢不熟悉的用戶;第三,可以根據(jù)用戶的需求定制數(shù)據(jù),同時(shí)保持?jǐn)?shù)據(jù)表的簡潔性,又不會(huì)占用很多的存儲(chǔ)空間,并且,在視圖中同樣可以對數(shù)據(jù)進(jìn)行增刪改的操作。
除了視圖,還可以用存儲(chǔ)過程來完成對成績的查詢。創(chuàng)建名為p1的存儲(chǔ)過程如下:
create procedure p1 as
select d1.stuid,d1.name,d2.cname,d3.score from stuinfo d1,course d2,score d3
where d1.stuid=d3.stuid and d2.cid=d3.cid
需要查看成績的時(shí)候調(diào)用p1存儲(chǔ)過程:exec p1就可以查看所有學(xué)生的各門課程成績,如果需要針對某學(xué)生或某課程進(jìn)行查詢,則需要?jiǎng)?chuàng)建帶參數(shù)的存儲(chǔ)過程。
Create procedure p2(char(10))as
select d1.stuid,d1.name,d2.cname,d3.score from stuinfo d1,course d2,score d3
where d1.stuid=d3.stuid and d2.cid=d3.cid and d1.stuid=@sid
p2存儲(chǔ)過程可以通過學(xué)號(hào)查詢學(xué)生成績調(diào)用語句:exec p2“2015020202”
從上面三種實(shí)現(xiàn)多表數(shù)據(jù)查詢的方法來看,SQL語句查詢交互性強(qiáng),查詢靈活,但對于了解不多的用戶來說,多表復(fù)雜查詢會(huì)有一定的困難。視圖的優(yōu)點(diǎn)是可以防止未經(jīng)許可的用戶訪問敏感數(shù)據(jù);降低數(shù)據(jù)庫的復(fù)雜度;結(jié)果更容易理解,獲得數(shù)據(jù)更容易,應(yīng)用程序的維護(hù)更加方便,但需要數(shù)據(jù)庫設(shè)計(jì)者對數(shù)據(jù)操作有足夠的了解和預(yù)見,否則可能會(huì)限制系統(tǒng)功能;存儲(chǔ)過程的優(yōu)勢是可以包含邏輯控制語句和數(shù)據(jù)操作語句速度,模塊化和封裝能夠加快系統(tǒng)運(yùn)行,減少網(wǎng)絡(luò)流量,但它的靈活性不如前兩種方式。
[1]王永樂,徐書欣.S QLServer 2008數(shù)據(jù)庫管理及應(yīng)用[M].北京:清華大學(xué)出版社,2011.
[2]王勇.用關(guān)系數(shù)據(jù)庫標(biāo)準(zhǔn)語言S QL實(shí)現(xiàn)數(shù)據(jù)查詢(多表查詢)的應(yīng)用研究[J].計(jì)算機(jī)光盤軟件與應(yīng)用,2014(19):66-67.