第7章數(shù)據(jù)庫查詢_第1頁
第7章數(shù)據(jù)庫查詢_第2頁
第7章數(shù)據(jù)庫查詢_第3頁
第7章數(shù)據(jù)庫查詢_第4頁
第7章數(shù)據(jù)庫查詢_第5頁
已閱讀5頁,還剩94頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1第7章數(shù)據(jù)庫查詢所謂查詢,就是對數(shù)據(jù)庫內(nèi)的數(shù)據(jù)進(jìn)行檢索、創(chuàng)立、修改或刪除的特定請求。數(shù)據(jù)庫接受用T-SQL語言編寫的查詢。使用查詢可以按照不同的方式查看、更改和分析數(shù)據(jù)。查詢設(shè)計是數(shù)據(jù)庫應(yīng)用程序開發(fā)的重要組成局部,因為在設(shè)計數(shù)據(jù)庫并用數(shù)據(jù)進(jìn)行填充后,需要通過查詢來使用數(shù)據(jù)。查詢分兩大類:一類是用于數(shù)據(jù)檢索的選擇查詢,另一類是用于數(shù)據(jù)更新的操作查詢。7.1SELECT查詢語法在SQLServer中,可以通過SELECT語句來實現(xiàn)查詢,即從數(shù)據(jù)庫表中檢索所需要的數(shù)據(jù)。查詢可以包含:要返回的列要選擇的行放置行的順序如何將信息分組的標(biāo)準(zhǔn)。SELECT語句的語法格式如下:SELECTselect_list[INTOnew_table_name]FROMtable_list[WHEREsearch_conditions][GROUPBYgroup_by_list][HAVINGsearch_conditions][ORDERBYorder_list[ASC|DESC]]7.2.1投影查詢通過SELECT語句的<select_list>項組成結(jié)果表的列。投影查詢的格式如下:SELECT[ALL|DISTINCT][TOPn[PERCENT]{*|{{column_name|expression|IDENTITYCOL|ROWGUIDCOL}

[[AS]column_alias]|column_alias=expression}[,…n]}7.2簡單查詢1.選擇一個表中指定的列使用SELECT語句選擇一個表中的某些列,各列名之間要以逗號分隔?!纠?-1】查詢teaching數(shù)據(jù)庫student中學(xué)生的姓名、性別和專業(yè)。USE

teachingSELECT

sname,ssex,specialtyFROM

student【例7-2】查詢teaching數(shù)據(jù)庫course表中所有記錄。USEteachingSELECT*FROMcourse用“*〞表示表中所有的列,按用戶創(chuàng)立表格時聲明列的順序來顯示所有的列?!纠?-3】查詢teaching數(shù)據(jù)庫student表的專業(yè)名稱,濾掉重復(fù)行。USEteachingSELECTDISTINCTspecialtyFROMstudent用DISTINCT關(guān)鍵字可以過濾掉查詢結(jié)果中的重復(fù)行?!纠?-4】查詢teaching數(shù)據(jù)庫course表前三行信息。USE

teachingSELECT

top3*FROM

course【例7-5】查詢teaching數(shù)據(jù)庫course前50%。USE

teachingSELECT

top50percent*

FROM

course2.改變查詢結(jié)果中標(biāo)題的顯示T-SQL提供了在SELECT語句中操作列名的方法。用戶可以根據(jù)實際需要對查詢數(shù)據(jù)的列標(biāo)題進(jìn)行改變,或者為沒有標(biāo)題的列加上臨時標(biāo)題。常用的方式:①在列表達(dá)式后面給出列名。②用“=〞來連接列表達(dá)式。③用AS關(guān)鍵字來連接列表達(dá)式和指定的列名。【例7-6】查詢student表中所有學(xué)生的學(xué)號、姓名,將結(jié)果中各列標(biāo)題分別指定為漢字“學(xué)號〞和“姓名〞。USEteachingSELECTsnoAS學(xué)號,snameAS姓名FROMstudent或:SELECT學(xué)號=sno,姓名=snameFROMstudent或:SELECTsno學(xué)號,sname姓名FROMstudent注意:查詢語句中改變的只是本次查詢的列的顯示標(biāo)題,對原表中列標(biāo)題沒有任何影響。3.計算列值在進(jìn)行數(shù)據(jù)查詢時,經(jīng)常需要對查詢到的數(shù)據(jù)進(jìn)行再次計算處理。T-SQL允許直接在SELECT語句中使用計算列。計算列并不存在于表格所存儲的數(shù)據(jù)中,它是通過對某些列的數(shù)據(jù)進(jìn)行演算得來的結(jié)果,所以沒有列名?!纠?-7】查詢sc表,按150分制計算成績。USE

teachingSELECTsno,cno,score150=score*1.50

FROMsc7.2.2選擇查詢投影查詢時從列的角度進(jìn)行的查詢,一般對行不進(jìn)行任何過濾〔DISTINCT除外〕。但是,一般的查詢都不是針對全表所有行的查詢,只是從整個表中選出滿足指定條件的內(nèi)容,這就要用到WHERE子句進(jìn)行選擇查詢。選擇查詢的根本語法如下:SELECTSELECT_LISTFROMTABLE_LISTWHERESEARCH_CONDITIONS(選擇查詢的條件)課本P131表7-11.使用關(guān)系表達(dá)式比較運算符用于比較兩個表達(dá)式的值,共有7個:=〔等于〕、<〔小于〕、<=〔小于等于〕、>〔大于〕、>=〔大于等于〕、<>〔不等于〕、!=〔不等于〕、!<〔不小于〕、!>〔不大于〕。比較運算的格式為:expression{=|<|<=|>|>=|<>|!=|!<|!>}expression其中expression是除text、ntext和image外類型的表達(dá)式?!纠?-8】查詢teaching數(shù)據(jù)庫的sc表中成績大于等于60的學(xué)生的學(xué)號、課程號和成績。USEteachingSELECT

*

FROMsc

WHERE

score>=602.使用邏輯表達(dá)式邏輯運算符共有3個,它們是:NOT:非,對表達(dá)式的否認(rèn)。AND:與,連接多個條件,所有的條件都成立時為真。OR:或,連接多個條件,只要有一個條件成立就為真?!纠?-9】查詢teaching數(shù)據(jù)庫中“計算機(jī)〞專業(yè)的“男〞生的信息。USEteachingSELECT*FROMstudentWHEREspecialty='計算機(jī)'ANDssex='男'【例7-10】查詢teaching數(shù)據(jù)庫中“計算機(jī)〞專業(yè)的或“男〞生的信息。USEteachingSELECT*FROMstudentWHEREspecialty='計算機(jī)'ORssex='男'3.使用BETWEEN關(guān)鍵字使用BETWEEN關(guān)鍵字可以更方便地限制查詢數(shù)據(jù)的范圍。其語法格式為:表達(dá)式[NOT]BETWEEN表達(dá)式1AND表達(dá)式2使用BETWEEN表達(dá)式進(jìn)行查詢的效果完全可以用含有“>=〞和“<=〞的邏輯表達(dá)式來代替,使用NOTBETWEEN進(jìn)行查詢的效果完全可以用含有“>〞和“<〞的邏輯表達(dá)式來代替?!纠?-11】查詢teaching數(shù)據(jù)庫中成績在80到90之間的學(xué)生的學(xué)號、課程號和成績。USEteachingSELECT

*

FROMscWHERE

score

BETWEEN

80AND90或:USEteachingSELECT

*FROMscWHERE

score>=80AND

score<=90【例7-12】查詢teaching數(shù)據(jù)庫中成績不在80到90之間的學(xué)生的學(xué)號、課程號和成績。USEteachingSELECT

*

FROMscWHEREscore

NOTBETWEEN80AND904.使用IN〔屬于〕關(guān)鍵字同BETWEEN關(guān)鍵字一樣,IN的引入也是為了更方便地限制檢索數(shù)據(jù)的范圍。語法格式為:表達(dá)式[NOT]IN(表達(dá)式1,表達(dá)式2[,…表達(dá)式n])【例7-13】查詢teaching數(shù)據(jù)庫中“計算機(jī)〞和“通信〞專業(yè)的學(xué)生的姓名、學(xué)號和專業(yè)。USEteachingSELECTsname,sno,specialtyFROMstudentWHEREspecialtyIN('計算機(jī)','通信')5.使用LIKE關(guān)鍵字(模糊查詢)LIKE關(guān)鍵字搜索與指定模式匹配的字符串、日期或時間值。模式包含要搜索的字符串,字符串中可包含4種通配符的任意組合,搜索條件中可用的通配符。通配符含義%包含零個或多個字符的任意字符串_任何單個字符[]代表指定范圍內(nèi)的單個字符,[]中可以是單個字符(如[acef]),也可以是字符范圍(如[a-f])[^]代表不在指定范圍內(nèi)的單個字符,[^]中可以是單個字符(如[^acef]),也可以是字符范圍(如[^a-f])【例7-14】通配符的例如LIKE'AB%'返回以“AB〞開始的任意字符串。LIKE'Ab%'返回以“Ab〞開始的任意字符串。LIKE'%abc'返回以“abc〞結(jié)束的任意字符串。LIKE'%abc%'返回包含“abc〞的任意字符串。LIKE'_ab'返回以“ab〞結(jié)束的三個字符的字符串。LIKE'[ACK]%'返回以“A〞、“C〞或“K〞開始的任意字符串。LIKE‘[A-T]ing’返回四個字符的字符串,結(jié)尾是“ing〞,首字符的范圍從A到T。LIKE'M[^c]%'返回以“M〞開始且第二個字符不是“c〞的任意長度的字符串?!纠?-15】查詢teaching數(shù)據(jù)庫中所有姓“張〞的學(xué)生的信息。USEteachingSELECT*FROMstudentWHEREsnamelike'張%'6.IS[NOT]NULL(是[否]為空)查詢在WHERE子句中不能使用比較運算符對空值進(jìn)行判斷,只能使用空值表達(dá)式來判斷某個表達(dá)式是否為空值。語法格式:表達(dá)式ISNULL或表達(dá)式ISNOTNULL【例7-16】查詢teaching數(shù)據(jù)庫中所有“成績〞為空值的學(xué)生的學(xué)號、課程號和成績。USEteachingSELECT*FROMscWHEREscoreISNULL7.復(fù)合條件查詢在WHERE子句中可以使用邏輯運算符把假設(shè)干個搜索條件合并起來,組成復(fù)雜的復(fù)合搜索條件。這些邏輯運算符包括AND、OR和NOT。AND運算符:表示只有在所有條件都為真時,才返回真。OR運算符:表示只要有一個條件為真時,就可以返回真。NOT運算符:取反。當(dāng)在一個WHERE子句中,同時包含多個邏輯運算符時,其優(yōu)先級從高到低依次是NOT、AND、OR。【例7-17】從teaching的student表中查詢所有“計算機(jī)〞和“通信〞專業(yè)的“女〞生的信息。USEteachingSELECT*FROMstudentWHEREssex='女'AND(specialty='計算機(jī)'ORspecialty='通信')7.2.3聚合函數(shù)查詢SQLServer提供了一系列聚合函數(shù)。這些函數(shù)把存儲在數(shù)據(jù)庫中的數(shù)據(jù)描述為一個整體而不是一行行孤立的記錄,通過使用這些函數(shù)可以實現(xiàn)數(shù)據(jù)集合的匯總或是求平均值等各種運算。表7-3常用的聚合函數(shù)函數(shù)名功能sum(列名)返回一個數(shù)字列的總和avg(列名)對一個數(shù)字列計算平均值min(列名)返回一個數(shù)字、字符或日期列的最小值max(列名)返回一個數(shù)字、字符或日期列的最大值count(列名)返回一個列的數(shù)據(jù)項數(shù)count(*)返回找到的行數(shù)在SELECT子句中可以使用聚合函數(shù)進(jìn)行運算,運算結(jié)果作為新列出現(xiàn)在結(jié)果集中。在聚合運算的表達(dá)式中,可以包括列名、常量以及由算術(shù)運算符連接起來的函數(shù)。【例7-18】在teaching中查詢sc表中成績的平均值,平均值顯示列標(biāo)題為“平均成績〞。USEteachingSELECTavg(score)AS平均成績FROMsc【例7-19】從數(shù)據(jù)庫teaching的student中查詢專業(yè)的種類〔相同的按一種計算〕。USEteachingSELECTcount(DISTINCTspecialty)AS專業(yè)種類數(shù)FROMstudent說明:在T-SQL中,允許與統(tǒng)計函數(shù)如count()、sum()和avg()一起使用DISTINCT關(guān)鍵字來處理列或表達(dá)式中不同的值。【例7-20】在teaching中查詢的1302001號學(xué)生的平均成績。USEteachingSELECTavg(score)AS平均成績FROMscWHEREsno=’1302001’在MicrosoftSQLServer2019系統(tǒng)中,一般情況下可以在3個地方使用聚合函數(shù),即SELECT子句、COMPUTE子句和HAVING子句。7.3分組和匯總分組:聚合函數(shù)+GROUPBY匯總:SELECT中使用COMPUTE7.3.1分組查詢使用聚合函數(shù)返回的是所有行數(shù)據(jù)的統(tǒng)計結(jié)果。如果需要按某一列數(shù)據(jù)的值進(jìn)行分類,在分類的根底上再進(jìn)行查詢,就要使用GROUPBY子句了。分組技術(shù)是指使用GROUPBY子句完成分組操作的技術(shù)。GROUPBY子句的語法結(jié)構(gòu)如下:[GROUPBY[ALL]group_by_expression[,…n][WITH{CUBE|ROLLUP}]]1.簡單分組如果在GROUPBY子句中沒有使用CUBE或ROLLUP關(guān)鍵字,那么表示這種分組的技術(shù)是簡單分組技術(shù)。【例7-21】查詢teaching中男生和女生的人數(shù)。USEteachingSELECTssex,count(ssex)人數(shù)FROMstudent

GROUPBYssex注意:指定GROUPBY子句時,選擇列表中任意非聚合表達(dá)式內(nèi)的所有列都應(yīng)包含在GROUPBY列表中〔不能使用別名列〕,或者GROUPBY表達(dá)式必須與選擇列表表達(dá)式完全匹配。當(dāng)完成數(shù)據(jù)結(jié)果的查詢和統(tǒng)計后,可以使用HAVING關(guān)鍵字來對查詢和統(tǒng)計的結(jié)果進(jìn)行進(jìn)一步的篩選?!纠?-22】在sc表中查詢選修了兩門及以上課程的學(xué)生學(xué)號和選課數(shù)。USEteachingSELECTsno,COUNT(cno)選修課程數(shù)FROMscGROUPBYsnoHAVINGCOUNT(cno)>=2HAVING與WHERE子句的區(qū)別是:WHERE

子句式對整表中數(shù)據(jù)篩選滿足條件的行;而HAVING子句是對GROUPBY分組查詢后產(chǎn)生的組加條件,篩選出滿足條件的組。另外,WHERE中條件不能使用聚合函數(shù),HAVING中條件一般使用聚合函數(shù)。2.CUBE和ROLLUP的使用1〕CUBE指定在結(jié)果集內(nèi)不僅包含由GROUPBY提供的行,還包含匯總行。GROUPBY匯總行在結(jié)果中顯示為NULL,但用來表示所有值。結(jié)果集內(nèi)的匯總行數(shù)取決于GROUPBY子句內(nèi)包含的列數(shù)。GROUPBY子句中的每個操作數(shù)〔列〕綁定在分組NULL下,并且分組適用于所有其他操作數(shù)〔列〕。由于CUBE返回每個可能的組和子組組合,因此不管在列分組時指定使用什么順序,行數(shù)都相同?!纠?-23】在teaching中查詢sc表,求被選修的各門課程的平均成績和選修該課程的人數(shù)。USEteachingSELECTcno,AVG(score)AS'平均成績',COUNT(sno)AS'選修人數(shù)'FROMscGROUPBYcno

WITHCUBE【例7-24】在teaching中查詢student,統(tǒng)計各專業(yè)男生、女生人數(shù)及每個專業(yè)的學(xué)生人數(shù)和男生總?cè)藬?shù)、女生人數(shù)以及所有學(xué)生總?cè)藬?shù)。USEteaching

SELECTspecialty,ssex,COUNT(*)AS'人數(shù)'

FROMstudentGROUPBYspecialty,ssex

WITHCUBE2〕ROLLUPROLLUP指定在結(jié)果集內(nèi)不僅包含由GROUPBY提供的行,還包含匯總行。按層次結(jié)構(gòu)順序,從組內(nèi)的最低級別到最高級別匯總組。組的層次結(jié)構(gòu)取決于列分組時指定使用的順序。更改列分組的順序會影響在結(jié)果集內(nèi)生成的行數(shù)。使用CUBE或ROLLUP時,不支持區(qū)分性聚合函數(shù),如AVG(DISTINCTcolumn_name)COUNT(DISTINCTcolumn_name)、SUM(DISTINCTcolumn_name)?!纠?-25】統(tǒng)計在teaching庫中每個專業(yè)的男、女生人數(shù),每個專業(yè)的總?cè)藬?shù)和所有學(xué)生總?cè)藬?shù)。USEteachingSELECTspecialty,ssex,COUNT(*)AS'人數(shù)'FROMstudentGROUPBYspecialty,ssexWITHROLLUP7.3.2數(shù)據(jù)匯總當(dāng)在SELECT子句中出現(xiàn)聚合函數(shù)時,結(jié)果集中的數(shù)據(jù)全是聚合值,沒有明細(xì)值。這是使用SELECT子句計算聚合值的缺點。能否解決這種問題呢,答案是肯定的,解決問題的方法就是使用COMPUTE子句。在SELECT語句中使用COMPUTE子句時,查詢結(jié)果由兩個局部組成:前一局部就是未用COMPUTE子句時產(chǎn)生的結(jié)果集;后一局部只有一行,是由COMPUTE子句產(chǎn)生附加的匯總數(shù)據(jù),出現(xiàn)在整個結(jié)果集的末尾。COMPUTE子句有兩種形式,一種形式是不帶BY子句,另一種形式是帶BY子句。COMPUTE子句的語法格式如下:[COMPUTE{聚合函數(shù)名〔expression〕}[,…n][BYexpression[,…n]]注意:AVG|COUNT|MAX|MIN|SUM這些函數(shù)均會忽略NULL值,且DISTINCT選項不能在此使用?!纠?-26】在teaching中查詢“計算機(jī)〞專業(yè)的學(xué)生的學(xué)號、姓名和性別,并統(tǒng)計學(xué)生總?cè)藬?shù)。USEteachingSELECTsno,sname,ssexFROMstudentWHEREspecialty='計算機(jī)'COMPUTECOUNT(sno)【例7-27】在teaching中查詢所有學(xué)生的選課信息,并計算每個學(xué)生的平均成績。USEteachingSELECTsno,cno,scoreFROMscORDERBYsnoCOMPUTEavg(score)BYsno7.4連接查詢以上的查詢操作都是從一個表中檢索數(shù)據(jù)。在實際應(yīng)用中,經(jīng)常需要同時從兩個表或兩個以上表中檢索數(shù)據(jù),并且每一個表中的數(shù)據(jù)往往作為一個單獨的列出現(xiàn)在結(jié)果集中。實現(xiàn)從兩個或兩個以上表中檢索數(shù)據(jù)且結(jié)果集中出現(xiàn)的列來自于兩個或兩個以上表中的檢索操作被稱為連接技術(shù),或者說連接技術(shù)是指對兩個表或兩個以上表中數(shù)據(jù)執(zhí)行乘積運算的技術(shù)。7.4.1內(nèi)連接(兩個表及以上)

內(nèi)連接把兩個表中的數(shù)據(jù)連接生成第三個表,第三個表中僅包含那些滿足連接條件的數(shù)據(jù)行。在內(nèi)連接中,使用INNERJOIN連接運算符,并且使用ON關(guān)鍵字指定連接條件。內(nèi)連接是一種常用的連接方式,如果在JOIN關(guān)鍵字前面沒有明確指定連接類型,那么默認(rèn)的連接類型是內(nèi)連接。內(nèi)連接的語法格式如下:SELECTselect_listFROM表1INNERJOIN表2ON連接條件或SELECTselect_listFROM表1,表2WHERE連接條件連接條件格式為:[<表名1>.]<列名1><比較運算符>[<表名2>.]<列名2>【例7-28】從teaching中查詢每個學(xué)生的姓名、課程號和成績。USEteaching

SELECTFROMstudent

INNERJOINscON也可以利用下面的程序來實現(xiàn):USEteachingSELECTFROMstudent,scWHERE注意:在列名不同時,列名前可以不加表名,但有時也會加上表名,以增強可讀性?!纠?-29】從teaching中查詢“計算機(jī)〞專業(yè)的學(xué)生所選課程的平均分。USEteachingSELECTbo,avg(b.score)as平均分FROMstudentaINNERJOINscbONanda.specialty='計算機(jī)'GROUPBY為簡化輸入,可在SELECT查詢的FROM子句中為表定義一個臨時別名。7.4.2自連接〔一個表,兩個副本之間〕連接操作不僅可以在不同的表上進(jìn)行,而且在同一張表內(nèi)可以進(jìn)行自身連接,即將同一個表的不同行連接起來。自連接可以看作一張表的兩個副本之間的連接。在自連接中,必須為表指定兩個別名,使之在邏輯上成為兩張表?!纠?-30】從teaching中查詢同名學(xué)生的信息。USEteachingSELECT*FROMstudentaINNERJOINstudentbONAND7.4.3外連接(兩個表及以上)在外連接中,不僅包括那些滿足條件的數(shù)據(jù),而且某些表不滿足條件的數(shù)據(jù)也會顯示在結(jié)果集中。也就是說,外連接只限制其中一個表的數(shù)據(jù)行,而不限制另外一個表中的數(shù)據(jù)。這種連接形式在許多情況下是非常有用的,例如在連鎖超市統(tǒng)計報表時,不僅要統(tǒng)計那些有銷售量的超市和商品,而且還要統(tǒng)計那些沒有銷售量的超市和商品。(1)外連接的分類在MicrosoftSQLServer2019系統(tǒng)中,可以使用的3種外連接關(guān)鍵字,即LEFTOUTERJOIN、RIGHTOUTERJOIN和FULLOUTERJOIN。①左外連接是對連接條件中左邊的表不限制;②右外連接是對右邊的表不限制;③全外連接對兩個表都不限制,所有兩個表中的行都會包括在結(jié)果集中。(2)外連接的語法①左外連接SELECTselect_list

FROM

表1LEFT[OUTER]JOIN表2

ON

表1.列1=表2.列2②右外連接SELECTselect_list

FROM

表1RIGHT[OUTER]JOIN

表2

ON表1.列1=表2.列2③全外連接SELECTselect_list

FROM

表1FULL[OUTER]JOIN表2

ON表1.列1=表2.列2【例7-31】在teaching中查詢每個學(xué)生及其選修課程的成績情況〔含未選課的學(xué)生信息〕。USEteachingSELECTFROMstudentLEFTJOINscON【例7-32】在teaching中查詢每個學(xué)生及其選修課程的情況(含未選課的學(xué)生信息及未被選修的課程信息)。

USEteaching

SELECT

FROMcourse

FULLJOINsc

ON

FULLJOINstudent

ON【例7-33】在teaching中查詢成績在75分以上的學(xué)生的學(xué)號、姓名,選修課的課程號、課程名、成績。USEteachingSELECT

FROMstudent

ASAJOINsc

ASBON

ANDB.score>75JOINcourse

ASCON7.4.4交叉連接(兩個表及以上)交叉連接也被稱為笛卡爾乘積,返回兩個表的乘積。在檢索結(jié)果集中,包含了所連接的兩個表中所有行的全部組合。例如,假設(shè)對A表和B表執(zhí)行交叉連接,A表中有5行數(shù)據(jù),B表中有12行數(shù)據(jù),那么結(jié)果集中可以有60行數(shù)據(jù)。交叉連接使用CROSSJOIN關(guān)鍵字來創(chuàng)立。實際上,交叉連接的使用是比較少的,但是交叉連接是理解外連接和內(nèi)連接的根底。語法格式如下:SELECT列FROM表1CROSSJOIN表2【例7-34】在teaching中查詢所有學(xué)生可能的選課情況。USEteachingSELECTFROMstudentaCROSSJOINscb7.5子查詢SELECT語句可以嵌套在其他許多語句中,這些語句包括SELECT、INSERT、UPDATE及DELETE等,這些嵌套的SELECT語句被稱為子查詢。當(dāng)一個查詢依賴于另外一個查詢結(jié)果時,那么可以使用子查詢。在某些查詢中,查詢語句比較復(fù)雜不容易理解,因此為了把這些復(fù)雜的查詢語句分解成多個比較簡單的查詢語句形式時常使用子查詢方式。使用子查詢方式完成查詢操作的技術(shù)是子查詢技術(shù)。子查詢可以分為無關(guān)子查詢〔嵌套子查詢〕和相關(guān)子查詢。7.5.1無關(guān)子查詢〔嵌套子查詢〕只執(zhí)行一次無關(guān)子查詢的執(zhí)行不依賴于外部查詢。無關(guān)子查詢在外部查詢之前執(zhí)行,然后返回數(shù)據(jù)供外部查詢使用,無關(guān)子查詢中不包含對于外部查詢的任何引用。1.比較子查詢使用子查詢進(jìn)行比較測試時,通過等于〔=〕、不等于〔<>〕、小于〔<〕、大于〔>〕、小于或等于〔<=〕以及大于或等于〔>=〕等比較運算符,將一個表達(dá)式的值與子查詢返回的單值進(jìn)行比較。如果比較運算的結(jié)果為TRUE,那么比較測試也返回TRUE?!纠?-35】在teaching中查詢與“沈艷〞在同一個專業(yè)學(xué)習(xí)的學(xué)生的學(xué)號、姓名和專業(yè)。USEteachingSELECTsno,sname,specialtyFROMstudentWHEREspecialty=〔SELECTspecialtyFROMstudentWHEREsname='沈艷')例7-35可以用自連接來實現(xiàn),程序如下:USEteachingSELECTa.sno,a.sname,a.specialtyFROMstudent

a,student

bWHEREa.specialty=b.specialtyANDb.sname='沈艷'需要特別指出的是,子查詢的SELECT語句不能使用ORDERBY子句,ORDERBY子句只能對最終查詢結(jié)果排序?!纠?-36】在teaching中查詢C001號課的考試成績比“鄭麗〞高的學(xué)生的學(xué)號和姓名。USEteachingSELECTstudent.sno,snameFROMstudent,scWHEREandcno='C001'ANDscore>(SELECTscoreFROMscWHEREcno='C001'ANDsno=(SELECTsnoFROMstudentWHEREsname='鄭麗'))2.SOME、ANY、ALL和IN子查詢ALL和ANY操作符的常見用法是結(jié)合一個相比照較操作符對一個數(shù)據(jù)列子查詢的結(jié)果進(jìn)行測試。它們測試比較值是否與子查詢所返回的全部或一局部值匹配。比方說,如果比較值小于或等于子查詢所返回的每一個值,<=ALL將是true;只要比較值小于或等于子查詢所返回的任何一個值,<=ANY將是true。SOME是ANY的一個同義詞。【例7-37】查詢teaching中計算機(jī)專業(yè)年齡最大的學(xué)生的學(xué)號和姓名。USEteachingSELECTsno,sname

FROMstudent

WHEREsage>=ALL

(SELECTsage

FROMstudent

WHEREspecialty='計算機(jī)')ANDspecialty='計算機(jī)'【例7-38】查詢teaching中與任何一個通信專業(yè)同齡的學(xué)生的信息。USEteachingSELECT*FROMstudent

WHEREsage=ANY

(SELECTsage

FROMstudent

WHEREspecialty='通信')實際上,IN和NOTIN操作符是=ANY和<>ALL的簡寫。也就是說,IN操作符的含義是“等于子查詢所返回的某個數(shù)據(jù)行〞,NOTIN操作符的含義是“不等于子查詢所返回的任何數(shù)據(jù)行〞?!纠?-39】在teaching中查詢選修了“C001〞號課程的學(xué)生姓名和所在專業(yè)。USEteachingSELECTsname,specialtyFROMstudentWHEREsnoIN(SELECTsnoFROMscWHEREcno='C001')3.子查詢結(jié)果作為主查詢的查詢對象【例7-40】在teaching中查詢有兩個以上學(xué)生的平均成績超過80分的班級〔用年級和專業(yè)表示〕。USEteachingSELECTgrade,specialtyFROMstudents,(SELECTsnoFROMscGROUPBYsnoHAVINGAVG(score)>=80)ssWHEREs.sno=ss.snoGROUPBYgrade,specialtyHAVINGCOUNT(*)>=27.5.2相關(guān)子查詢(重復(fù)地執(zhí)行)相關(guān)子查詢中,子查詢的執(zhí)行依賴于外部查詢,多數(shù)情況下是子查詢的WHERE子句中引用了外部查詢的表。相關(guān)子查詢的執(zhí)行過程與嵌套子查詢完全不同,嵌套子查詢中子查詢只執(zhí)行一次,而相關(guān)子查詢中的子查詢需要重復(fù)地執(zhí)行。相關(guān)子查詢的執(zhí)行過程:①子查詢?yōu)橥獠坎樵兊拿恳恍袌?zhí)行一次,外部查詢將子查詢引用的列的值傳給子查詢。②假設(shè)子查詢?nèi)魏涡信c其匹配,外部查詢就返回結(jié)果行。③再回到第一步,直到處理完外部表的每一行。1.比較子查詢【例7-41】在teaching中查詢成績比該課的平均成績低的學(xué)生的學(xué)號、課程號、成績。USEteachingSELECTsno,cno,scoreFROMscaWHEREscore<(SELECTavg(score)FROMscbWHEREao=bo)【例7-42】在teaching中查詢有兩門以上課程的成績在80分以上的學(xué)生的學(xué)號、姓名、年級和專業(yè)。USEteachingSELECTsno,sname,grade,specialtyFROMstudentsWHERE

(SELECTCOUNT(*)FROMscWHEREsc.sno=s.snoANDscore>=80)>=22.帶有EXISTS的子查詢〔存在性測試〕使用子查詢進(jìn)行存在性測試時,通過邏輯運算符EXISTS或NOTEXISTS,檢查子查詢所返回的結(jié)果集是否有行存在。使用邏輯運算符EXISTS時,如果在子查詢的結(jié)果集內(nèi)包含有一行或多行,那么存在性測試返回TRUE;如果該結(jié)果集內(nèi)不包含任何行,那么存在性測試返回FALSE。在EXISTS前面加上NOT時,將對存在性測試結(jié)果取反。帶有EXISTS謂詞的子查詢不返回任何數(shù)據(jù),只產(chǎn)生邏輯真值“TRUE〞或邏輯假值“

FALSE〞?!纠?-43】在teaching中查詢所有選修了“C004〞課程的學(xué)生姓名。分析:本查詢涉及“學(xué)生〞和“選課〞關(guān)系。我們可以在student中依次取每個元組的“學(xué)號〞值,用此值去檢查“選課〞關(guān)系。假設(shè)選課表中存在這樣的元組,其“學(xué)號〞值等于student中“學(xué)號〞的值,并且其課程號=’C004’,那么取此學(xué)生的“姓名〞送入結(jié)果關(guān)系。USEteachingSELECTsnameFROMstudentWHEREEXISTS(SELECT*FROMscANDcno=’C004’)由EXISTS引出的子查詢,其目標(biāo)屬性列表達(dá)式一般用*表示,因為帶EXISTS的子查詢只返回真值或假值,給出列名無實際意義。假設(shè)內(nèi)層子查詢結(jié)果非空,那么外層的WHERE子句條件為真〔TRUE〕,否那么為假〔FALSE〕。使用子查詢時要注意以下幾點:1)子查詢需要用括號()括起來。2)子查詢可以嵌套。3)子查詢的SELECT語句中不能使用image、text和ntext數(shù)據(jù)類型。4)子查詢返回的結(jié)果的數(shù)據(jù)類型必須匹配外圍查詢WHERE語句的數(shù)據(jù)類型。5)子查詢中不能使用ORDERBY子句。7.6其它查詢7.6.1集合運算查詢1.UNION聯(lián)合查詢聯(lián)合查詢是指將兩個或兩個以上的SELECT語句通過UNION運算符連接起來的查詢,聯(lián)合查詢可以將兩個或更多查詢的結(jié)果組合為單個結(jié)果集,該結(jié)果集包含聯(lián)合查詢中所有查詢的全部行。使用UNION組合兩個查詢的結(jié)果集的兩個根本規(guī)那么是:所有查詢中的列數(shù)和列的順序必須相同;數(shù)據(jù)類型必須兼容。其語法格式如下:Select_statementUNION[ALL]Select_statement[UNION[ALL]Select_statement[...n]]其中的參數(shù)說明如下:①Select_statement:是參與查詢的SELECT語句。②ALL:在結(jié)果中包含所有的行,包括重復(fù)行;如果沒有指定,那么刪除重復(fù)行?!纠?-44】查詢選修了課程“C001〞和課程“C004〞的學(xué)生的姓名。USEteachingSELECTsnameFROMsc,studentUNIONSELECTsnameFROMsc,student2.EXCEPT和INTERSECTEXCEPT和INTERSECT運算符可以比較兩個或多個SELECT語句的結(jié)果并返回非重復(fù)值。EXCEPT運算符返回由EXCEPT運算符左側(cè)的查詢返回、而又不包含在右側(cè)查詢所返回的值中的所有非重復(fù)值。INTERSECT返回由INTERSECT運算符左側(cè)和右側(cè)的查詢都返回的所有非重復(fù)值。使用EXCEPT和INTERSECT的根本規(guī)那么同UNION。語法格式如下:Select_statement{EXCEPT|INTERSECT}Select_statement【例7-45】查詢沒有選課的學(xué)生的學(xué)號。SELECTsnoFROMstudentEXCEPTSELECTsno

FROMsc【例7-46】查詢既選修了C001號課程又選修了C004課程的學(xué)生的姓名。SELECTsname

FROMsc,studentINTERSECTSELECTsanmeFROMsc,student7.6.2對查詢結(jié)果排序在使用SELECT語句時,排序是一種常見的操作。排序是指按照指定的列或其他表達(dá)式對結(jié)果集進(jìn)行排列順序的方式。SELECT語句中的ORDERBY子句負(fù)責(zé)完成排序操作。其語法格式如下:[ORDERBY{order_by_expression[ASC|DESC]}[,...n]] ASC是升序,DESC是降序,默認(rèn)情況下是升序。【例7-47】查詢teaching中“女〞學(xué)生的姓名和專業(yè),并按姓名升序排列。USEteachingSELECTsname,specialtyFROMstudentWHEREssex=’女’ORDERBYsnameASC【例7-48】查詢sc表中學(xué)生的成績和學(xué)號,并按成績降序排列。USEteachingSELECTsno,scoreFROMscORDERBYscoreDESC【例7-49】查詢sc表中學(xué)生的成績和學(xué)號,并按成績〔降序〕排列,假設(shè)成績相同按學(xué)號〔升序〕排列。USEteachingSELECTsno,scoreFROMscORDERBYscoreDESC,snoASC【例7-50】使用TOP關(guān)鍵字查詢course中“學(xué)分〞最高的前兩門課。USEteachingSELECTTOP2cname,creditFROMcourseORDERBYcreditDESC7.6.3存儲查詢結(jié)果通過在SELECT語句中使用INTO子句,可以創(chuàng)立一個新表并將查詢結(jié)果中的行添加到該表中。用戶在執(zhí)行一個帶有INTO子句的SELECT語句時,必須擁有在目標(biāo)數(shù)據(jù)庫上創(chuàng)立表的權(quán)限。SELECT...INTO不能與COMPUTE子句一起使用。SELECT...INTO語句的語法格式如下:SELECTselect_listINTOnew_tableFROMtable_source[WHEREsearch_condition]【例7-51】在teaching中將查詢的學(xué)生姓名,學(xué)號,課程名,成績的相關(guān)數(shù)據(jù)存放在表“成績單〞中。并對新表進(jìn)行查詢。USEteachingSELECTsname,student.sno,cname,scoreINTO成績單FROMstudent,sc,courseGOSELECT*FROM成績單7.7在數(shù)據(jù)操作中使用SELECT子句可以在INSERT語句、UPDATE語句和DELETE語句中使用SELECT子句來完成相應(yīng)的數(shù)據(jù)插入、修改和刪除。7.7.1在INSERT語句中使用SELECT子句在INSERT語句中使用SELECT子句可以將一個或多個表或視圖中的值添加到另一個表中。使用SELECT子句還可以同時插入多行。語法形式為:INSERT[INTO]table_name[(column_list)]SELECTselect_listFROMtable_name[WHEREsearch_condit

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論