《數(shù)據(jù)庫(kù)原理與SQL 2012應(yīng)用教程》課件-第8章 數(shù)據(jù)查詢(xún)_第1頁(yè)
《數(shù)據(jù)庫(kù)原理與SQL 2012應(yīng)用教程》課件-第8章 數(shù)據(jù)查詢(xún)_第2頁(yè)
《數(shù)據(jù)庫(kù)原理與SQL 2012應(yīng)用教程》課件-第8章 數(shù)據(jù)查詢(xún)_第3頁(yè)
《數(shù)據(jù)庫(kù)原理與SQL 2012應(yīng)用教程》課件-第8章 數(shù)據(jù)查詢(xún)_第4頁(yè)
《數(shù)據(jù)庫(kù)原理與SQL 2012應(yīng)用教程》課件-第8章 數(shù)據(jù)查詢(xún)_第5頁(yè)
已閱讀5頁(yè),還剩61頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

ISBN978-7-111-50122-0第8章

數(shù)據(jù)查詢(xún)數(shù)據(jù)查詢(xún),也稱(chēng)為數(shù)據(jù)檢索,是數(shù)據(jù)庫(kù)的一個(gè)最重要也是最基本的功能,它是從數(shù)據(jù)庫(kù)中檢索符合條件的數(shù)據(jù)記錄的選擇過(guò)程。SQLServer2012的數(shù)據(jù)查詢(xún)使用T-SQL語(yǔ)言,其基本的查詢(xún)語(yǔ)句是SELECT語(yǔ)句。本章主要介紹數(shù)據(jù)查詢(xún)語(yǔ)句的語(yǔ)法及使用。8.1數(shù)據(jù)查詢(xún)語(yǔ)句使用數(shù)據(jù)庫(kù)的主要目的是存儲(chǔ)數(shù)據(jù),以便在需要時(shí)進(jìn)行檢索、統(tǒng)計(jì)或組織輸出。數(shù)據(jù)查詢(xún)是數(shù)據(jù)庫(kù)的核心操作。T-SQL語(yǔ)言提供了SELECT語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)的查詢(xún),是T-SQL語(yǔ)言中使用頻率最高的語(yǔ)句,可以說(shuō)是T-SQL語(yǔ)言的靈魂。該語(yǔ)句具有靈活的使用方式和豐富的功能,用戶(hù)可以借助它實(shí)現(xiàn)各種各樣的查詢(xún)需求。其主要語(yǔ)法格式如下:SELECTselect_list[INTOnew_table][FROMtable_source][WHEREsearch_condition][GROUPBYgroup_by_expression][HAVINGsearch_condition][ORDERBYorder_expression[ASC|DESC]]8.1數(shù)據(jù)查詢(xún)語(yǔ)句SELECT語(yǔ)句語(yǔ)法說(shuō)明:1)SELECT語(yǔ)句后的select_list中有多種關(guān)鍵字選項(xiàng)。ALL表示顯示所有查詢(xún)結(jié)果,DISTINCT表示不重復(fù)顯示查詢(xún)結(jié)果,TOP<operator>表示顯示查詢(xún)結(jié)果的前n條記錄或前n%條記錄。還可以給列、表達(dá)式命名別名。也可以使用函數(shù),包括系統(tǒng)函數(shù)和用戶(hù)定義函數(shù)。2)FROM子句的table_source是表或視圖名,而且有多種連接方式。3)WHERE子句的search_condition可以是單一的,也可以是組合的查詢(xún)條件。4)GROUPBY子句的group_by_expression是分組條件表達(dá)式,對(duì)記錄進(jìn)行分組。5)HAVING子句的search_condition也是條件表達(dá)式,選擇滿(mǎn)足條件的分組結(jié)果。6)ORDERBY子句的order_expression是排序表達(dá)式。ASC是升序,DESC是降序。默認(rèn)是ASC。7)整個(gè)SELECT語(yǔ)句的含義是,從FROM子句指定的基本表或視圖中讀取記錄。如果有WHERE子句,根據(jù)WHERE子句的條件表達(dá)式,選擇符合條件的記錄。如果有GROUPBY子句,根據(jù)GROUPBY子句的條件表達(dá)式,對(duì)記錄進(jìn)行分組。如果有HAVING子句,根據(jù)HAVING子句的條件表達(dá)式,選擇滿(mǎn)足條件的分組結(jié)果。如果有ORDERBY子句,根據(jù)ORDERBY子句的條件表達(dá)式,將按指定的列的取值排序。最后根據(jù)SELECT語(yǔ)句指定列,輸出最終的結(jié)果。如果有INTO子句,則將查詢(xún)結(jié)果存儲(chǔ)到指定的表中。8.1數(shù)據(jù)查詢(xún)語(yǔ)句8)SELECT語(yǔ)句中的子句順序非常重要??梢允÷钥蛇x子句,但這些子句在使用時(shí)必須按適當(dāng)?shù)捻樞虺霈F(xiàn)。SELECT語(yǔ)句的處理順序依次是:FROMONJOINWHEREGROUPBYWITHCUBE或WITHROLLUPHAVINGSELECTDISTINCTORDERBYTOP9)SELECT語(yǔ)句通過(guò)對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)查詢(xún)操作,完全可以實(shí)現(xiàn)關(guān)系模型的3種基本關(guān)系運(yùn)算:投影、選擇和連接。8.1.1投影列投影列指的是通過(guò)限定返回結(jié)果的列組成結(jié)果表。1.投影指定列投影指定列指的是投影一個(gè)表中的部分列,各列名之間用逗號(hào)隔開(kāi)?!纠?-1】

查詢(xún)Student表中學(xué)號(hào)、姓名和性別。USECOLLEGEGOSELECTStudentID,Name,SexFROMStudentGO8.1.1投影列【例8-2】

查詢(xún)Employee表中員工的姓名和出生日期。USEPUBLISHGOSELECTName,BirthdayFROMAuthorGO8.1.1投影列2.投影所有列投影所有列指的是投影一個(gè)表中的全部列??梢詫⑺辛忻剂谐?,各列之間用逗號(hào)隔開(kāi),也可以使用符號(hào)“*”?!纠?-3】

查詢(xún)Course表所有課程的信息。USECOLLEGEGOSELECTCourseID,CourseName,CreditFROMCourseGO或USECOLLEGEGOSELECT*FROMCourseGO8.1.1投影列3.定義列別名查詢(xún)結(jié)果默認(rèn)輸出的列名都是建表時(shí)的列名。但有時(shí)用戶(hù)希望查詢(xún)結(jié)果顯示自己指定的列名,這時(shí)就可以定義表列的別名。SELECT語(yǔ)句使用AS關(guān)鍵字來(lái)定義別名?!纠?-4】

查詢(xún)School表所有學(xué)院的信息,SchoolID列名用“學(xué)院編號(hào)”,SchoolName列名用“學(xué)院名稱(chēng)”顯示。USECOLLEGEGOSELECTSchoolIDAS'學(xué)院編號(hào)',SchoolNameAS'學(xué)院名稱(chēng)'FROMSchoolGO查詢(xún)結(jié)果如圖8-4所示。查詢(xún)結(jié)果顯示的列名不是建表時(shí)的列名,而是定義的別名。定義表列的別名也可以用“=”。【例8-4】等同于:USECOLLEGEGOSELECT'學(xué)院編號(hào)'=SchoolID,'學(xué)院名稱(chēng)'=SchoolNameFROMSchoolGO8.1.1投影列或USECOLLEGEGOSELECT學(xué)院編號(hào)=SchoolID,學(xué)院名稱(chēng)=SchoolNameFROMSchoolGO用“=”定義列別名時(shí),列別名可以用單引號(hào)引起來(lái),也可以不用。但如果列別名中有空格,則必須使用單引號(hào)引起來(lái)。8.1.1投影列4.替換結(jié)果中數(shù)據(jù)在對(duì)表進(jìn)行查詢(xún)時(shí),有時(shí)希望對(duì)所查詢(xún)的某些列使用表達(dá)式進(jìn)行計(jì)算。SELECT語(yǔ)句支持表達(dá)式的使用?!纠?-5】

查詢(xún)Course表,將每門(mén)課的學(xué)分加10,并顯示一個(gè)數(shù)字為“10”的列。USECOLLEGEGOSELECTCourseID,CourseName,Credit+10,10FROMCourseGO8.1.1投影列5.CASE表達(dá)式替換在替換查詢(xún)時(shí),經(jīng)常使用CASE表達(dá)式。CASE表達(dá)式用來(lái)計(jì)算條件列表并返回多個(gè)可能結(jié)果表達(dá)式之一。CASE表達(dá)式有兩種格式:1)CASE簡(jiǎn)單表達(dá)式,它通過(guò)將表達(dá)式與一組簡(jiǎn)單的表達(dá)式進(jìn)行比較來(lái)確定結(jié)果。2)CASE搜索表達(dá)式,它通過(guò)計(jì)算一組布爾表達(dá)式來(lái)確定結(jié)果。這兩種格式都支持可選的ELSE參數(shù)。CASE可用于允許使用有效表達(dá)式的任意語(yǔ)句或子句。例如,可以在SELECT、UPDATE、DELETE和SET等語(yǔ)句以及select_list、IN、WHERE、ORDERBY和HAVING等子句中使用CASE。8.1.1投影列【例8-6】

查詢(xún)Mark表,如果分?jǐn)?shù)大于等于80,則評(píng)為“優(yōu)秀”;大于等于60,則評(píng)為“及格”;小于60,則評(píng)為“不及格”。使用CASE表達(dá)式給每個(gè)學(xué)生的分?jǐn)?shù)設(shè)定等級(jí)。USECOLLEGEGOSELECTStudentID,CourseID,Score,RANK=CASEWHENScore>=80THEN'優(yōu)秀'WHENScore>=60THEN'及格'ELSE'不及格'ENDFROMMarkGO8.1.1投影列【例8-7】

查詢(xún)Student表,使用CASE表達(dá)式,根據(jù)學(xué)生性別,對(duì)該學(xué)生進(jìn)行描述。USECOLLEGEGOSELECTName,性別=CASESexWHEN'男'THEN'男生'WHEN'女'THEN'女生'ENDFROMStudentGO8.1.2選擇行選擇行指的是通過(guò)限定返回結(jié)果的行組成結(jié)果表。選擇行可以和投影列一起使用。1.消除結(jié)果中的重復(fù)行在對(duì)表進(jìn)行查詢(xún)時(shí),有時(shí)查詢(xún)結(jié)果有許多重復(fù)行。SELECT語(yǔ)句使用DISTINCT關(guān)鍵字消除結(jié)果中的重復(fù)行。其語(yǔ)法格式如下:DISTINCTcolumn_name[,column_name…]DISTINCT關(guān)鍵字對(duì)后面的所有列消除重復(fù)行。一個(gè)SELECT語(yǔ)句中DISTINCT只能出現(xiàn)一次,而且必須放在所有列名之前。【例8-8】

查詢(xún)PUBLISH表,使用DISTINCT顯示性別。USEPUBLISHGOSELECTDISTINCTSexAS'性別'FROMAuthorGO8.1.2選擇行2.限制結(jié)果返回行數(shù)如果SELECT語(yǔ)句返回結(jié)果有很多行,可以使用TOP關(guān)鍵字限定返回行數(shù)。其語(yǔ)法格式如下:TOPn[PERCENT]其中n表示返回結(jié)果的前n行,nPERCENT表示返回結(jié)果的前n%行。n可以是常數(shù),也可以是常量、變量或數(shù)值表達(dá)式?!纠?-9】

查詢(xún)PUBLISH表中前50%的作者的姓名和性別。USEPUBLISHGOSELECTTOP50PERCENTName,SexFROMAuthorGO【例8-10】

查詢(xún)Course表中前3門(mén)課程的課程名和學(xué)分。USECOLLEGEGODECLARE@nINTSET@n=3SELECTTOP(@n)CourseName,CreditFROMCourseGO8.1.2選擇行3.限制結(jié)果返回行的條件在限定返回結(jié)果的行操作時(shí),最重要的就是通過(guò)條件限制,SELECT語(yǔ)句中WHERE子句是最常用、最重要的條件子句。在WHERE子句中指出查詢(xún)的條件,系統(tǒng)找出符合條件的結(jié)果。其語(yǔ)法格式如下:WHERE<operator1>[AND<operator2>…][AND|OR<operator>…]T-SQL提供了各種運(yùn)算符和關(guān)鍵字來(lái)定義查詢(xún)條件。(1)表達(dá)式比較在WHERE子句中對(duì)表達(dá)式進(jìn)行比較時(shí),可以使用比較運(yùn)算符和邏輯運(yùn)算符?!纠?-11】

查詢(xún)課程分?jǐn)?shù)大于90的信息。USECOLLEGEGOSELECT*FROMMarkWHEREScore>90GO8.1.2選擇行【例8-12】

查詢(xún)年齡小于20歲的女生的姓名。USECOLLEGEGOSELECTNameAS'姓名'FROMStudentWHEREDATEDIFF(YEAR,Birthday,GETDATE())<20ANDSex='女'GO8.1.2選擇行(2)限制取值在查詢(xún)數(shù)據(jù)時(shí),如果條件較多,需要使用多個(gè)OR運(yùn)算符,這樣就使代碼顯得冗長(zhǎng)。T-SQL提供了IN關(guān)鍵字來(lái)取代多個(gè)OR運(yùn)算符,表示如果表達(dá)式的取值與值表中的任意一個(gè)值匹配,即返回TRUE?!纠?-13】

查詢(xún)北京和上海的作者的姓名和省份名稱(chēng)。USEPUBLISHGOSELECTName,ProvincesFROMAuthorWHEREProvincesIN('北京','上海')GO查詢(xún)結(jié)果如圖8-14所示。本例查詢(xún)使用了IN子句來(lái)限制取值,結(jié)果與下列語(yǔ)句等價(jià):USEPUBLISHGOSELECTName,ProvincesFROMAuthorWHEREProvinces='北京'ORProvinces='上海'GO8.1.2選擇行(3)限制范圍在查詢(xún)數(shù)據(jù)時(shí),有時(shí)需要限定范圍。T-SQL提供了BETWEEN關(guān)鍵字來(lái)取限制范圍,可以取代多個(gè)關(guān)系運(yùn)算符和邏輯運(yùn)算符(即等同于使用>=、<=和AND限制的范圍),表示如果表達(dá)式的取值在限定范圍中即返回TRUE。【例8-14】

查詢(xún)?cè)?0世紀(jì)70年代出生的作者信息。USEPUBLISHGOSELECT*FROMAuthorWHEREYEAR(Birthday)BETWEEN1970AND1979GO8.1.2選擇行(4)模式匹配在查詢(xún)數(shù)據(jù)時(shí),有時(shí)并不知道查詢(xún)范圍或者準(zhǔn)確的信息,只知道查詢(xún)的模式或者大概的信息。T-SQL提供了LIKE關(guān)鍵字來(lái)限定模式匹配查詢(xún)。LIKE關(guān)鍵字只能用于匹配字符串?dāng)?shù)據(jù)。LIKE模式匹配時(shí)可以使用表8-1中的通配符。表8-1LIKE模式匹配的通配符通

符說(shuō)明%匹配0個(gè)或多個(gè)任意字符_匹配1個(gè)任意字符[]匹配集合中的任意單個(gè)字符[^]不匹配集合中的任意單個(gè)字符8.1.2選擇行【例8-15】

查詢(xún)姓“趙”的女生的信息。USECOLLEGEGOSELECT*FROMStudentWHERENameLIKE'趙%'ANdSex='女'GO本例查詢(xún)使用了LIKE來(lái)限定學(xué)生姓名的匹配模式,結(jié)果輸出了姓王的男生的信息,包括名字是兩個(gè)字和三個(gè)字的。8.1.2選擇行【例8-16】

查詢(xún)姓“張”且名字是3個(gè)字的員工姓名。USEPUBLISHGOSELECTNameFROMAuthorWHERENameLIKE'張%'ANDLEN(Name)=3GO本例查詢(xún)使用了LIKE來(lái)限定學(xué)生姓名的匹配模式。如果用LIKE'張__'(兩個(gè)下劃線(xiàn)),結(jié)果將顯示姓張的職工信息,包括名字是兩個(gè)字和三個(gè)字的。所以用LEN求字符數(shù)函數(shù)可以準(zhǔn)確得到姓名是3個(gè)字。8.1.2選擇行例8-17】

查詢(xún)不姓“張”的員工姓名。USEPUBLISHGOSELECTNameFROMAuthorWHERENameLIKE'[^張]%'GO本例查詢(xún)使用了LIKE來(lái)限定學(xué)生姓名的匹配模式。[^張]表示不匹配字符集“張”,即第1個(gè)字符不是字符“張”。在T-SQL中,“=”、IN和LIKE都可以用來(lái)進(jìn)行數(shù)據(jù)匹配。一般情況下,“=”用來(lái)查詢(xún)單個(gè)值的精確匹配;IN用來(lái)查詢(xún)多個(gè)值的精確匹配;LIKE用來(lái)查詢(xún)多個(gè)值的模糊匹配。8.1.2選擇行5)空值處理當(dāng)需要判斷一個(gè)表達(dá)式或表數(shù)據(jù)是否為空,T-SQL提供了ISNULL或NULL關(guān)鍵字來(lái)判斷?!纠?-18】

查詢(xún)省份信息沒(méi)有登記的作者信息。USEPUBLISHGOSELECT*FROMAuthorWHEREProvincesISNULLGO本例查詢(xún)使用了ISNULL來(lái)判斷分?jǐn)?shù)列取值是否為空??罩挡皇菙?shù)值0,也不是空格字符串,而是取值為NULL(沒(méi)有輸入數(shù)據(jù))或未知。8.1.3連接進(jìn)行數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí),由于規(guī)范化、數(shù)據(jù)的一致性及完整性等要求,每個(gè)表中的數(shù)據(jù)都是有限的,但一個(gè)數(shù)據(jù)庫(kù)中的各個(gè)表又不是孤立的,存在一定關(guān)系。這時(shí)就不得不將多個(gè)表連接在一起,進(jìn)行組合查詢(xún)數(shù)據(jù)。在一些特殊情況下,一個(gè)表還可以與自身連接。連接指的是通過(guò)限定返回結(jié)果,將多個(gè)表的數(shù)據(jù)組成結(jié)果表,即用一個(gè)SELECT語(yǔ)句可以完成從多個(gè)表中查詢(xún)的數(shù)據(jù)。連接對(duì)結(jié)果沒(méi)有特別的限制,具有很大的靈活性。T-SQL提供了兩種連接方式:傳統(tǒng)連接方式和SQL連接方式。1.傳統(tǒng)連接方式傳統(tǒng)連接方式是指使用FROM…WHERE連接多表。其語(yǔ)法格式如下:SELECTselect_listFROMtable_name[,table_name,…]WHEREcondition使用傳統(tǒng)連接方式時(shí),必須將連接的所有表或視圖名放在FROM后,而連接條件或選擇條件放在WHERE后。8.1.3連接【例8-19】

查詢(xún)每名男同學(xué)的姓名和所在學(xué)院的名稱(chēng)。USECOLLEGEGOSELECTName,SchoolNameFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSex='男'GO本例查詢(xún)使用傳統(tǒng)連接方式,連接時(shí)在FROM子句中將所有表寫(xiě)出,WHERE子句中寫(xiě)出連接條件和查詢(xún)條件。8.1.3連接【例8-20】

查詢(xún)計(jì)算機(jī)學(xué)院的學(xué)生選修課程信息。USECOLLEGEGOSELECTName,SchoolName,Course.CourseName,Mark.ScoreFROMStudent,School,Mark,CourseWHEREStudent.StudentID=Mark.StudentIDANDCourse.CourseID=Mark.CourseIDANDSchool.SchoolName='計(jì)算機(jī)學(xué)院'GO連接查詢(xún)時(shí),如果多表中有重名屬性列,必須在列名前標(biāo)注表名。如果沒(méi)有重名屬性列,表名可以省略。8.1.3連接2.SQL連接方式SQL連接方式是指使用JOIN…ON連接多表。其語(yǔ)法格式如下:SELECTselect_listFROMtable_nameJOINtable_name[JOINtable_name…]ONconditionWHEREcondition使用SQL連接方式時(shí),必須將連接的所有表或視圖名放在FROM后,用JOIN…ON連接起來(lái),連接條件放在ON后,而選擇條件則放在WHERE后。8.1.3連接例8-21】

查詢(xún)所有學(xué)生姓名、選修課程名稱(chēng)和分?jǐn)?shù)。USECOLLEGEGOSELECTName,CourseName,ScoreFROMStudentJOINMarkJOINCourseONCourse.CourseID=Mark.CourseIDONStudent.StudentID=Mark.StudentIDGO本例查詢(xún)結(jié)果使用SQL連接方式,連接時(shí)在FROM子句中將所有表用JOIN連接,ON子句中寫(xiě)出連接條件,WHERE子句中寫(xiě)出選擇條件。由于是3個(gè)表連接,需要兩個(gè)JOIN連接和兩個(gè)ON子句,因?yàn)?個(gè)表是兩兩連接。但注意,JOIN連接和ON條件是有順序的。當(dāng)改變表的JOIN連接順序或ON子句順序后,結(jié)果就不一定正確,甚至于提示出錯(cuò)。8.1.3連接SQL連接方式又分為內(nèi)連接、外連接、交叉連接。其語(yǔ)法格式如下:[INNER|{LEFT|RIGHT|FULL}[OUTER][CROSS][<join_hint>]JOIN說(shuō)明:1)INNER表示內(nèi)連接,是系統(tǒng)默認(rèn)的連接方式。2)OUTER表示外連接。外連接又分為左外連接(LEFT)、右外連接(RIGHT)、完全外連接(FULL)。左外連接的結(jié)果集中除了包括滿(mǎn)足條件的行外,還包括左表所有的行。右外連接的結(jié)果集中除了包括滿(mǎn)足條件的行外,還包括右表所有的行。完全外連接的結(jié)果集中除了包括滿(mǎn)足條件的行外,還包括左右兩表所有的行。3)CROSS表示交叉連接,又稱(chēng)為自然連接,即生成一個(gè)笛卡爾積。4)<join_hint>表示外連接提示。8.1.3連接【例8-22】

查詢(xún)學(xué)生選修的課程的情況,輸出學(xué)號(hào)和課程名,如果有課程沒(méi)有學(xué)生選修,也輸出。USECOLLEGEGOSELECTStudentID,CourseNameFROMCourseLEFTJOINMarkONCourse.CourseID=mark.CourseIDGO本例使用了左外連接,將滿(mǎn)足條件的學(xué)生的學(xué)號(hào)和課程名輸出。如果Course表中還有不滿(mǎn)足條件的記錄也輸出,但在StudentID列中以NULL值輸出,表示此門(mén)課程沒(méi)有學(xué)生選修。8.1.3連接【例8-23】

查詢(xún)學(xué)生選修課程的情況,輸出姓名和課程號(hào),如果有學(xué)生沒(méi)有選修課程,也輸出。USECOLLEGEGOSELECTName,Mark.CourseIDFROMMarkRIGHTJOINStudentONMark.StudentID=Student.StudentIDGO本例使用了右外連接,將滿(mǎn)足條件的學(xué)生的姓名和課程號(hào)輸出。如果學(xué)生表中還有不滿(mǎn)足條件的記錄也輸出,但在CourseID列中以NULL值輸出,表示此學(xué)生沒(méi)有選修任何課程。8.1.3連接【例8-24】

查詢(xún)所有學(xué)生選修所有課程的情況。USECOLLEGEGOSELECTName,CourseNameFROMStudentCROSSJOINCourseGO本例使用了交叉連接,生成一個(gè)由Student表和Course表組成的笛卡爾積?!纠?-25】

自連接。USECOLLEGEGOSELECTa.CourseID,a.ScoreFROMMarkaJOINMarkbONa.StudentID=b.StudentIDGO自連接時(shí),必須給表分別起別名加以區(qū)分。T-SQL提供的這兩種連接方式,一般用戶(hù)習(xí)慣使用傳統(tǒng)連接方式,除非是外部連接和交叉連接,因?yàn)閭鹘y(tǒng)連接方式的語(yǔ)法簡(jiǎn)單。8.2數(shù)據(jù)匯總在對(duì)表數(shù)據(jù)進(jìn)行查詢(xún)時(shí),經(jīng)常需要對(duì)結(jié)果進(jìn)行匯總計(jì)算。T-SQL提供了聚合函數(shù)對(duì)數(shù)據(jù)進(jìn)行計(jì)算。【例8-26】

統(tǒng)計(jì)選修了102號(hào)課程的學(xué)生的總分、平均分、最高分和最低分。USECOLLEGEGOSELECTSUM(Score)AS'總分',AVG(Score)AS'平均分',MAX(Score)AS'最高分',MIN(Score)AS'最低分'FROMMarkWHERECourseID='102'GO8.2數(shù)據(jù)匯總【例8-27】

統(tǒng)計(jì)作者人數(shù)。USEPUBLISHGOSELECTCOUNT(*)AS'作者人數(shù)',COUNT(Provinces)AS'登記有所在省份的作者人數(shù)'FROMAuthorGO本例查詢(xún)使用了聚合函數(shù)COUNT(*)和COUNT(column_name),它們都用來(lái)統(tǒng)計(jì)行數(shù)據(jù)個(gè)數(shù),但結(jié)果不一樣。COUNT(*)統(tǒng)計(jì)行個(gè)數(shù),COUNT(column_name)統(tǒng)計(jì)列中取值不為空的數(shù)據(jù)項(xiàng)個(gè)數(shù)。8.3排序默認(rèn)情況下,查詢(xún)結(jié)果是按照表記錄物理順序輸出的。但在實(shí)際應(yīng)用中經(jīng)常要對(duì)查詢(xún)結(jié)果排序輸出。本節(jié)主要介紹通過(guò)對(duì)數(shù)據(jù)進(jìn)行排序再輸出。T-SQL提供了ORDERBY子句對(duì)查詢(xún)結(jié)果排序。其語(yǔ)法格式如下:SELECTselect_listFROMtable_nameWHEREconditionORDERBYcolumn_name|alias|position[ASC|DESC]說(shuō)明:在ORDERBY后可以包含多種元素,可以是列名,可以是列別名,也可以是列在select_list中出現(xiàn)的位置。關(guān)鍵字ASC表示將結(jié)果按升序排序,關(guān)鍵字DESC表示將結(jié)果按降序排序。排序關(guān)鍵字可以省略,默認(rèn)按升序排序。8.3排序例8-28】

查詢(xún)計(jì)算機(jī)學(xué)院學(xué)生信息,并按年齡從高到低排序輸出USECOLLEGEGOSELECTName,SchoolName,BirthdayFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSchoolName='計(jì)算機(jī)學(xué)院'ORDERBYBirthdayGO年齡從高到低排序其實(shí)是按照Birthday值的升序排序的。8.3排序例8-29】

查詢(xún)學(xué)生成績(jī)信息,并按課程號(hào)和成績(jī)的升序輸出。USECOLLEGEGOSELECTName,CourseName,ScoreFROMStudent,Course,MarkWHEREStudent.StudentID=Mark.StudentIDANDCourse.CourseID=Mark.CourseIDORDERBYMark.CourseIDDESC,ScoreGO如果ORDERBY后有多列需要排序,按照從左向右的順序依次排序。本例先按CourseID值降序排序輸出,如果CourseID值相同,再按Score值的升序排序。8.4分組使用聚合函數(shù)可以統(tǒng)計(jì)數(shù)據(jù),但有時(shí)需要統(tǒng)計(jì)不同類(lèi)別的數(shù)據(jù)。T-SQL提供了GROUPBY子句對(duì)查詢(xún)結(jié)果分組。其語(yǔ)法格式如下:SELECTselect_listFROMtable_nameWHEREconditionGROUPBYcolumn_name[HAVINGcondition]|[WITHCUBE|ROLLUP]說(shuō)明:使用GROUPBY子句時(shí),GROUPBY后的column_name必須出現(xiàn)在SELECT后的select_list中,或者出現(xiàn)在聚合函數(shù)中,否則不允許分組。如果GROUPBY后的column_name有多個(gè),則表示多次分組。HAVING表示將分組結(jié)果再選擇。WITHCUBE或WITHROLLUP表示將分組結(jié)果再統(tǒng)計(jì)。如果使用GROUPBY子句時(shí)沒(méi)有使用聚合函數(shù),GROUPBY子句就失去了分組的意義,作用等同于使用DISTINCT關(guān)鍵字。8.4分組【例8-30】

統(tǒng)計(jì)每門(mén)課程的總分和平均分,并按平均分從高到低排序輸出。USECOLLEGEGOSELECTCourseID,SUM(Score)AS'總分',AVG(Score)AS'平均分'FROMMarkGROUPBYMark.CourseIDORDERBYAVG(Score)DESCGO本例查詢(xún)使用了GROUPBY子句,按照CourseID值對(duì)數(shù)據(jù)分組,CourseID值相同的記錄被分為一組,再分別進(jìn)行統(tǒng)計(jì)總分和平均分,最后按平均分的降序輸出結(jié)果。8.4分組【例8-31】

統(tǒng)計(jì)每個(gè)學(xué)院學(xué)生的男女生人數(shù)。USECOLLEGEGOSELECTSchoolName,Sex,COUNT(*)AS'人數(shù)'FROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDGROUPBYSchoolName,SexGO本例查詢(xún)使用了GROUPBY子句,按照SchoolName值和Sex值對(duì)數(shù)據(jù)分組,結(jié)果輸出每個(gè)學(xué)院學(xué)生的男女生人數(shù)。8.4分組比較以下語(yǔ)句:USECOLLEGEGOSELECTSchoolName,Sex,COUNT(*)AS'人數(shù)'FROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDGROUPBYSchoolName,SexGO如果GROUPBY子句后有多組分組,按照從右向左的順序依次分組。本例先按SchoolID值分組統(tǒng)計(jì),再按Sex值的分組統(tǒng)計(jì)。8.4分組【例8-32】統(tǒng)計(jì)每門(mén)課程選修的人數(shù),并輸出選修課程的總?cè)藬?shù)。USECOLLEGEGOSELECTCourseName,COUNT(*)AS'人數(shù)'FROMCourse,MarkWHERECourse.CourseID=Mark.CourseIDGROUPBYCourseNameWITHCUBEGO輸出結(jié)果不但有每門(mén)課程的選修人數(shù),并且在最后一行統(tǒng)計(jì)有全部人數(shù)。8.4分組【例8-33】

將【例8-31】修改為,不但統(tǒng)計(jì)每個(gè)學(xué)院學(xué)生的男女生人數(shù),同時(shí)再統(tǒng)計(jì)各個(gè)學(xué)院的總?cè)藬?shù)。USECOLLEGEGOSELECTSchoolName,Sex,COUNT(*)AS'人數(shù)'FROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDGROUPBYSchoolName,SexWITHROLLUPGO輸出結(jié)果不但統(tǒng)計(jì)每個(gè)學(xué)院學(xué)生的男女生人數(shù),同時(shí)再每個(gè)學(xué)院后面又添加了一行統(tǒng)計(jì),統(tǒng)計(jì)各個(gè)學(xué)院的總?cè)藬?shù)。8.4分組【例8-34】

統(tǒng)計(jì)各個(gè)省份男作者的人數(shù)。USEPUBLISHGOSELECTProvinces,Sex,COUNT(*)AS'人數(shù)'FROMAuthorGROUPBYProvinces,SexHAVINGSEX='男'GOHAVING子句是將分組統(tǒng)計(jì)后的結(jié)果再統(tǒng)計(jì)。如果將HAVING子句替換為WHERE字句,查詢(xún)結(jié)果相同。USEPUBLISHGOSELECTProvinces,Sex,COUNT(*)AS'人數(shù)'FROMAuthorWHERESEX='男'GROUPBYProvinces,SexGO8.4分組【例8-35】

查詢(xún)平均分在90分以上的課程名稱(chēng)和平均分。USECOLLEGEGOSELECTCourseName,AVG(Score)FROMStudent,Course,MarkWHEREStudent.StudentID=Mark.StudentIDANDCourse.CourseID=Mark.CourseIDGROUPBYCourseNameHAVINGAVG(Score)>=90GOHAVING子句是將分組統(tǒng)計(jì)后的結(jié)果再統(tǒng)計(jì)。8.5子查詢(xún)?cè)趯?shí)際應(yīng)用中,經(jīng)常有一些SELECT語(yǔ)句需要使用其他SELECT語(yǔ)句的查詢(xún)結(jié)果,此時(shí)需要子查詢(xún)。子查詢(xún)就是嵌套在另一個(gè)查詢(xún)(SELECT)語(yǔ)句中的查詢(xún)(SELECT)語(yǔ)句,因此,子查詢(xún)也稱(chēng)為嵌套查詢(xún)。外部的SELECT語(yǔ)句稱(chēng)為外圍查詢(xún)(父查詢(xún)),內(nèi)部的SELECT語(yǔ)句稱(chēng)為子查詢(xún)。子查詢(xún)的結(jié)果將作為外圍查詢(xún)的參數(shù),這種關(guān)系就好像是函數(shù)調(diào)用嵌套,將嵌套函數(shù)的返回值作為調(diào)用函數(shù)的參數(shù)。使用子查詢(xún)時(shí)要注意以下幾點(diǎn):1)子查詢(xún)需要用括號(hào)()括起來(lái)。2)子查詢(xún)可以嵌套。3)子查詢(xún)的SELECT語(yǔ)句中不能使用image、text和ntext數(shù)據(jù)類(lèi)型。4)子查詢(xún)返回的結(jié)果的數(shù)據(jù)類(lèi)型必須匹配外圍查詢(xún)WHERE語(yǔ)句的數(shù)據(jù)類(lèi)型。5)子查詢(xún)不能使用ORDERBY子句。子查詢(xún)具有兩種不同的處理方式:無(wú)關(guān)子查詢(xún)和相關(guān)子查詢(xún)。8.5.1無(wú)關(guān)子查詢(xún)無(wú)關(guān)子查詢(xún)指的是在外圍查詢(xún)之前執(zhí)行,然后返回?cái)?shù)據(jù)供外圍查詢(xún)使用,它和外圍查詢(xún)的聯(lián)系僅此而已。在編寫(xiě)嵌套子查詢(xún)的SQL語(yǔ)句時(shí),如果被嵌套的查詢(xún)中不包含對(duì)于外圍查詢(xún)的任何引用,就可以使用無(wú)關(guān)子查詢(xún)。最常用的無(wú)關(guān)子查詢(xún)方式是IN(或NOTIN)子句。其語(yǔ)法格式如下:SELECTselect_listFROMtable_nameWHEREcondition[NOT]IN(SELECTselect_listFROMtable_nameWHEREcondition)說(shuō)明:由關(guān)鍵字IN引入的子查詢(xún)的SELECT的select_list中只允許有一項(xiàng)內(nèi)容,即只能是一個(gè)列名或表達(dá)式。如果是IN,條件滿(mǎn)足則返回結(jié)果,否則不返回結(jié)果;如果是NOTIN,則相反,條件不滿(mǎn)足則返回結(jié)果。8.5.1無(wú)關(guān)子查詢(xún)【例8-36】

查詢(xún)年齡最小的學(xué)生的姓名和出生日期。USECOLLEGEGOSELECTName,BirthdayFROMStudentWHEREBirthdayIN(SELECTMAX(Birthday)FROMStudent)GO本例查詢(xún)使用了IN無(wú)關(guān)子查詢(xún)。先執(zhí)行子查詢(xún),求得年齡最小的Birthday值,然后返回結(jié)果供外圍查詢(xún)使用,最后結(jié)果輸出學(xué)生的學(xué)號(hào)和姓名。這里IN也可以用邏輯運(yùn)算符“=”替換,替換的前提是子查詢(xún)返回的結(jié)果集必須是一個(gè)惟一值。8.5.1無(wú)關(guān)子查詢(xún)【例8-37】

查詢(xún)選修了計(jì)算機(jī)網(wǎng)絡(luò)課程的學(xué)生的姓名。USECOLLEGEGOSELECTNameFROMStudentWHEREStudentIDIN(SELECTStudentIDFROMMarkWHERECourseIDIN(SELECTCourseIDFROMCourseWHERECourseName='計(jì)算機(jī)網(wǎng)絡(luò)'))GO本例查詢(xún)使用了IN無(wú)關(guān)子查詢(xún)嵌套。先執(zhí)行最里面的子查詢(xún)語(yǔ)句,求得線(xiàn)性代數(shù)課程的課程號(hào)。然后返回結(jié)果供外圍查詢(xún)使用,求得選修了這門(mén)課的學(xué)生的學(xué)號(hào)。最后返回結(jié)果供最外圍查詢(xún)使用,結(jié)果輸出學(xué)生的學(xué)號(hào)和姓名。8.5.1無(wú)關(guān)子查詢(xún)無(wú)關(guān)子查詢(xún)有時(shí)也可以使用連接等價(jià)替換。【例8-36】等同于以下連接:USECOLLEGEGOSELECTNameFROMStudent,Course,MarkWHEREStudent.StudentID=Mark.StudentIDANDMark.CourseID=Course.CourseIDANDCourseName='計(jì)算機(jī)網(wǎng)絡(luò)'GO無(wú)關(guān)子查詢(xún)除了可以使用IN子句,還經(jīng)常使用關(guān)系運(yùn)算符與邏輯運(yùn)算符(=,AND,SOME,ANY,ALL)。8.5.1無(wú)關(guān)子查詢(xún)【例8-38】

查詢(xún)比物理學(xué)院的學(xué)生年齡都大的其他學(xué)院的學(xué)生。USECOLLEGEGOSELECTName,SchoolNameFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSchoolName<>'物理學(xué)院'ANDBirthday<ALL(SELECTBirthdayFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSchoolName='物理學(xué)院')GO本例查詢(xún)使用了關(guān)系運(yùn)算符“<”與邏輯運(yùn)算符“ALL”。先執(zhí)行子查詢(xún)語(yǔ)句,求得物理學(xué)院所有學(xué)生的出生日期。然后返回結(jié)果供外圍查詢(xún)使用,ALL表示結(jié)果集的所有數(shù)據(jù),只有全部滿(mǎn)足才輸出。即只有當(dāng)不是物理學(xué)院的學(xué)生的出生日期大于了結(jié)果集中所有的數(shù)據(jù),結(jié)果才輸出。8.5.1無(wú)關(guān)子查詢(xún)?nèi)绻麑ⅰ纠?-38】中ALL改為SOME(或ANY),比較以下語(yǔ)句:USECOLLEGEGOSELECTName,SchoolNameFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSchoolName<>'物理學(xué)院'ANDBirthday<SOME(SELECTBirthdayFROMStudent,SchoolWHEREStudent.SchoolID=School.SchoolIDANDSchoolName='物理學(xué)院')GOSOME(或ANY)表示結(jié)果集中的任一數(shù)據(jù),如果有一個(gè)滿(mǎn)足關(guān)系表達(dá)式就輸出。即當(dāng)不是物理學(xué)院的學(xué)生的出生日期大于了結(jié)果集中的任一數(shù)據(jù),結(jié)果就輸出。關(guān)系運(yùn)算符用在子查詢(xún)時(shí),如果不用邏輯運(yùn)算符ALL、SOME、ANY(只用“=”),子查詢(xún)的結(jié)果集必須是一個(gè)值。8.5.2相關(guān)子查詢(xún)相關(guān)子查詢(xún)?cè)趫?zhí)行時(shí),要使用到外圍查詢(xún)的數(shù)據(jù)。外圍查詢(xún)首先選擇數(shù)據(jù)提供給子查詢(xún),然后子查詢(xún)對(duì)數(shù)據(jù)進(jìn)行比較,執(zhí)行結(jié)束后再將它的查詢(xún)結(jié)果返回到它的外圍查詢(xún)中。如果有結(jié)果返回,則外圍查詢(xún)輸出。相關(guān)子查詢(xún)通常使用關(guān)系運(yùn)算符與邏輯運(yùn)算符(EXISTS,AND,SOME,ANY,ALL)。8.5.2相關(guān)子查詢(xún)【例8-39】

查找所有選修課程的學(xué)生的姓名。USECOLLEGEGOSELECTDISTINCTNameFROMStudentWHEREEXISTS(SELECT*FROMMarkWHEREStudent.StudentID=Mark.StudentID)GO本例查詢(xún)使用了EXISTS相關(guān)子查詢(xún)。使用EXISTS關(guān)鍵字引入子查詢(xún)可以將該子查詢(xún)作為存在性測(cè)試,即測(cè)試是否存在滿(mǎn)足子查詢(xún)準(zhǔn)則的數(shù)據(jù)。如果子查詢(xún)返回的結(jié)果是空集,則判斷為不存在,即EXISTS失敗,NOTEXISTS成功。如果子查詢(xún)返回至少一行記錄,則判斷為存在,即EXISTS成功,NOTEXISTS失敗。關(guān)鍵字EXISTS一般直接跟在外圍查詢(xún)的WHERE關(guān)鍵字后面。它的前面沒(méi)有列名、常量或者表達(dá)式。子查詢(xún)的SELECT列表一般由“*”組成。關(guān)鍵字EXISTS一般與相關(guān)子查詢(xún)一起使用,在使用時(shí),對(duì)外表中的每一行子查詢(xún)都要運(yùn)行一遍,該行的值也要在子查詢(xún)的WHERE子句中被使用。這樣,通過(guò)EXISTS子句就能將外層表中的各行數(shù)據(jù)依次與子查詢(xún)處理的內(nèi)層表中的數(shù)據(jù)進(jìn)行存在性比較,得到所需的結(jié)果。8.5.2相關(guān)子查詢(xún)【例8-40】

查詢(xún)成績(jī)高于劉雨航最低分?jǐn)?shù)的學(xué)生的姓名、課程名和分?jǐn)?shù)。USECOLLEGEGOSELECTName,CourseName,ScoreFROMStudents,Coursec,MarkmWHEREs.StudentID=m.StudentIDANDc.CourseID=m.CourseIDANDm.Score>ANY(SELECTc.CreditFROMStudents,Coursec,MarkmWHEREs.StudentID=m.StudentIDANDc.CourseID=m.CourseIDANDs.Name='劉雨航')ANDs.Name<>'劉雨航'GO如果AND、ANY(或SOME)、ALL用于相關(guān)子查詢(xún)時(shí),一般都是多表子查詢(xún)。而且只能用在關(guān)系運(yùn)算符之后。子查詢(xún)使用的位置是非常靈活的,可以用在WHERE子句中,也可以用在其他子句中。8.5.2相關(guān)子查詢(xún)【例8-41】

查詢(xún)每個(gè)學(xué)生的平均分。USECOLLEGEGOSELECTName,平均分=(SELECTAVG(Score)FROMMarkmWHEREs.StudentID=m.StudentID)FROMStudentsGO本例子查詢(xún)使用在SELECT語(yǔ)句中使用子查詢(xún),輸出到列中。8.6集合操作SELECT查詢(xún)操作的對(duì)象是集合,結(jié)果也是集合。T-SQL提供了UNION、EXCEPT和INTERSECT三種集合操作。1.集合合并UNION將兩個(gè)或更多查詢(xún)的結(jié)果合并為單個(gè)結(jié)果集,該結(jié)果集包含聯(lián)合查詢(xún)中的所有查詢(xún)的全部行。UNION運(yùn)算不同于連接查詢(xún)。UNION合并兩個(gè)查詢(xún)結(jié)果集的基本規(guī)則是:1)所有查詢(xún)中的列數(shù)和

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論