項(xiàng)目6 數(shù)據(jù)查詢 SL修改_第1頁
項(xiàng)目6 數(shù)據(jù)查詢 SL修改_第2頁
項(xiàng)目6 數(shù)據(jù)查詢 SL修改_第3頁
項(xiàng)目6 數(shù)據(jù)查詢 SL修改_第4頁
項(xiàng)目6 數(shù)據(jù)查詢 SL修改_第5頁
已閱讀5頁,還剩105頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

數(shù)據(jù)查詢項(xiàng)目6【能力目標(biāo)】掌握簡單查詢,會(huì)使用SELECT語句查詢所有字段和指定的字段。掌握按條件查詢,會(huì)使用運(yùn)算符及不同的關(guān)鍵字進(jìn)行查詢。掌握高級(jí)查詢,會(huì)使用聚合函數(shù)查詢、分組查詢等。學(xué)會(huì)為表和字段起別名。學(xué)會(huì)使用交叉連接、內(nèi)連接、外連接及聯(lián)合條件連接查詢多表中的數(shù)據(jù)。掌握子查詢,會(huì)使用IN、EXISTS、ANY、ALL關(guān)鍵字及比較運(yùn)算符查詢多表中的數(shù)據(jù)?!舅仞B(yǎng)目標(biāo)】用不同的方法解決同一個(gè)問題,培養(yǎng)多種思路解決問題、從不同角度看問題的能力。目標(biāo)學(xué)習(xí)導(dǎo)航圖6-1項(xiàng)目6所講內(nèi)容在數(shù)據(jù)庫系統(tǒng)開發(fā)中的位置認(rèn)識(shí)基本的SELECT語句6.16.1.1

了解SELECT語句結(jié)構(gòu)SELECT語句可以從一個(gè)或多個(gè)表中選取符合某種條件的特定行和列,它是SQL的核心,其應(yīng)用結(jié)果通常是生成一個(gè)臨時(shí)表。如下。SELECT[ALL|DISTINCT]*|列名1[,列名2…,列名n]FROM數(shù)據(jù)表名…[WHERE條件表達(dá)式1][GROUPBY列名][HAVING條件表達(dá)式2][ORDERBY列名[ASC|DESC]][LIMIT[OFFSET]記錄數(shù)][PROCEDURE存儲(chǔ)過程名(參數(shù)…)][INTOOUTFILE'文件名'[格式]參數(shù)|INTODUMPFILE'文件名'|INTO變量名…][FORUPDATE|LOCKINSHAREMODE]

6.1.2

應(yīng)用聚合函數(shù)聚合函數(shù)通常用于對(duì)一組值進(jìn)行計(jì)算,然后返回唯一值,也被稱為組函數(shù)。常見的常用的聚合函數(shù)如表6-1所示。表6-1常用的聚合函數(shù)

6.1.2

應(yīng)用聚合函數(shù)1.COUNT()函數(shù)

COUNT()函數(shù)用于統(tǒng)計(jì)組中滿足給定條件的行數(shù)或總行數(shù),返回SELECT語句檢索到的行中非NULL值的數(shù)目,若找不到匹配項(xiàng),則返回0。COUNT()函數(shù)的語法格式如下。COUNT(表達(dá)式)【例6-1】求學(xué)生的總?cè)藬?shù)。SELECTCOUNT(*)AS'學(xué)生總數(shù)'FROMstudent;

執(zhí)行結(jié)果如圖6-2所?示。圖6-2學(xué)生總?cè)藬?shù)

6.1.2

應(yīng)用聚合函數(shù)【例6-2】統(tǒng)計(jì)備注不為空的學(xué)生數(shù)目。SELECTCOUNT(Note)AS'備注不為空的學(xué)生數(shù)目'FROMstudent;【例6-3】統(tǒng)計(jì)總學(xué)分在50分以上的人數(shù)。SELECTCOUNT(Total_Credit)AS'總學(xué)分在50分以上的人數(shù)'

FROMstudent

WHERETotal_Credit>50;

執(zhí)行結(jié)果如圖6-3所?示。圖6-3備注不為空的學(xué)生數(shù)目

圖6-4總學(xué)分在50分以上的人數(shù)

執(zhí)行結(jié)果如圖6-4所?示。

6.1.2應(yīng)用聚合函數(shù)2.MAX()函數(shù)和MIN()函數(shù)MAX()函數(shù)和MIN()函數(shù)分別用于求表達(dá)式中所有值項(xiàng)的最大值和最小值,語法格式如下。MAX/MIN([ALL|DISTINCT]表達(dá)式)【例6-4】求選修課程101的學(xué)生的最高分和最低?分。SELECTMAX(Grade),MIN(Grade)

FROMelective

WHEREC_ID='101';

執(zhí)行結(jié)果如圖6-5所?示。圖6-5選修課程101的學(xué)生的最高分和最低分

6.1.2應(yīng)用聚合函數(shù)3.SUM()函數(shù)和AVG()函數(shù)SUM()函數(shù)和AVG()函數(shù)分別用于求表達(dá)式中所有值項(xiàng)的總和與平均值,語法格式如下。SUM/AVG([ALL|DISTINCT]表達(dá)式)【例6-5】求學(xué)號(hào)為201101的學(xué)生所學(xué)課程的總成績。SELECTSUM(Grade)AS'課程總成績'

FROMelective

WHERES_ID='201101';

執(zhí)行結(jié)果如圖6-6所?示。圖6-6學(xué)號(hào)為201101的學(xué)生所學(xué)課程的總成績

6.1.2應(yīng)用聚合函數(shù)【例6-6】求選修課程101的學(xué)生的平均成績。SELECTAVG(Grade)AS'課程101平均成績'

FROMelective

WHEREC_ID='101';

執(zhí)行結(jié)果如圖6-7所?示。圖6-7選修課程101的學(xué)生的平均成績

6.1.2應(yīng)用聚合函數(shù)4.VARIANCE()函數(shù)和STDDEV()函數(shù)VARIANCE()函數(shù)和STDDEV()函數(shù)分別用于計(jì)算特定表達(dá)式中所有值的方差和標(biāo)準(zhǔn)差,語法格式如下。VARTANCE/STDDEV([ALL|DISTINCT]表達(dá)式)【例6-7】求選修課程101的學(xué)生的成績方?差。SELECTVARIANCE(Grade)

FROMelective

WHEREC_ID='101';

執(zhí)行結(jié)果如圖6-8所?示。圖6-8選修課程101的學(xué)生的成績方差

6.1.2應(yīng)用聚合函數(shù)【例6-8】求選修課程101的學(xué)生的成績標(biāo)準(zhǔn)差。SELECTSTDDEV(Grade)

FROMelective

WHEREC_ID='101';執(zhí)行結(jié)果如圖6-9所示。圖6-9選修課程101的學(xué)生的成績標(biāo)準(zhǔn)差

6.1.2應(yīng)用聚合函數(shù)5.GROUP_CONCAT()函數(shù)該函數(shù)返回來自一個(gè)組指定列的所有非NULL值,這些值一個(gè)接一個(gè)放置,中間用逗號(hào)隔開,并表示為一個(gè)長長的字符串。這個(gè)字符串的長度是有限制的,標(biāo)準(zhǔn)值是1024。該函數(shù)的語法格式如下。GROUP_CONCAT({[ALL|DISTINCT]表達(dá)式}|*)【例6-9】求選修課程102的學(xué)生的學(xué)號(hào)。SELECTGROUP_CONCAT(S_ID)

FROMelective

WHEREC_ID='102';

執(zhí)行結(jié)果如圖6-10所示。圖6-10選修課程102的學(xué)生的學(xué)號(hào)

6.1.2應(yīng)用聚合函數(shù)6.BIT_AND()函數(shù)、BIT_OR()函數(shù)和BIT_XOR()函數(shù)與二進(jìn)制運(yùn)算符|(或)、&(與)和^(異或)相對(duì)應(yīng)的聚合函數(shù)分別是BIT_OR()、BIT_AND()、BIT_XOR()。函數(shù)的語法格式如下。BIT_AND/BIT_OR/BIT_XOR({[ALL|DISTINCT]表達(dá)式}|*)【例6-10】有一個(gè)表bits,其中有一列bin_value上有3個(gè)INT類型的值:1、3、7,獲取在該列上應(yīng)用BIT_OR()的結(jié)果。SELECTbin(BIT_OR(bin_value))

FROMbits;使用單表查詢實(shí)現(xiàn)數(shù)據(jù)查詢6.2

6.2.1使用選擇輸出列1.選擇指定的列使用SELECT語句選擇一個(gè)表中的某些列,各列名之間要用逗號(hào)分隔,所有列用“*”表示,具體語法格式如下。語法格式如下。SELECT*|列名1,列名2,…FROM數(shù)據(jù)表名;【例6-11】查詢數(shù)據(jù)庫ssms的表student中所有學(xué)生的姓名、專業(yè)和總學(xué)分。SELECTName,Major,Total_CreditFROMstudent;

執(zhí)行結(jié)果如圖6-11所示。圖6-11表student中所有學(xué)生的姓名、專業(yè)和總學(xué)分

6.2.1使用選擇輸出列2.定義列別名查詢結(jié)果中的列在顯示時(shí)使用自定義的列名,則可以在列名之后使用AS子句,語法格式如下。SELECT…列名[AS列別名]【例6-12】查詢表student中軟件工程專業(yè)學(xué)生的Name、Major和Total_Credit列的數(shù)據(jù),結(jié)果中各列的標(biāo)題分別指定為姓名、專業(yè)和總學(xué)分。SELECTNameAS姓名,MajorAS專業(yè),Total_CreditAS總學(xué)分

FROMstudent

WHEREMajor='軟件工程';

執(zhí)行結(jié)果如圖6-12所示。圖6-12查詢自定義別名結(jié)果

6.2.1使用選擇輸出列3.替換查詢結(jié)果中的數(shù)據(jù)要替換查詢結(jié)果中的數(shù)據(jù),需要使用查詢中的CASE表達(dá)式。該函數(shù)的語法格式如下。CASE

WHEN條件1THEN表達(dá)式1

WHEN條件2THEN表達(dá)式2

ELSE表達(dá)式nEND

6.2.1使用選擇輸出列【例6-13】查詢表student中軟件工程專業(yè)各學(xué)生的學(xué)號(hào)、姓名和總學(xué)分,并對(duì)總學(xué)分按如下規(guī)則進(jìn)行替換:若總學(xué)分為空值,則替換為“尚未選課!”;若總學(xué)分小于41,則替換為“不及格!”;若總學(xué)分為41~49(包括41和49),則替換為“合格”;若總學(xué)分大于50,則替換為“優(yōu)秀”;總學(xué)分列的標(biāo)題更改為“成績等級(jí)”。SELECTS_ID,Name,

CASE

WHENTotal_CreditISNULLTHEN'尚未選課!'

WHENTotal_Credit<41THEN'不及格!'

WHENTotal_Credit>=41ANDTotal_Credit<=49THEN'合格'

ELSE'優(yōu)秀'

ENDAS成績等級(jí)

FROMstudentWHEREMajor='軟件工程';

執(zhí)行結(jié)果如圖6-13所?示。

6.2.1使用選擇輸出列圖6-13替換結(jié)果

6.2.1使用選擇輸出列4.計(jì)算列值SELECT的輸出列可使用表達(dá)式,語法格式如下。SELECT表達(dá)式…【例6-14】按150分制重新計(jì)算成績,顯示表elective中學(xué)號(hào)為201101的學(xué)生成績信息。SELECTS_ID,C_ID,Grade*1.5AS成績150

FROMelective

WHERES_ID=201101;

執(zhí)行結(jié)果如圖6-14所示。圖6-14重新計(jì)算結(jié)果

6.2.1使用選擇輸出列5.消除結(jié)果集中的重復(fù)行當(dāng)只選擇表的某些列時(shí),輸出的結(jié)果可能會(huì)出現(xiàn)重復(fù)行??梢允褂藐P(guān)鍵字DISTNCT或DISTINCTROW消除結(jié)果集中的重復(fù)行,語法格式如下。SELECTDISTINCT|DISTINCTROW列名…【例6-15】只選擇數(shù)據(jù)庫ssms表student中的專業(yè)和總學(xué)分,并消除結(jié)果集中的重復(fù)行進(jìn)行顯示。SELECTDISTINCTMajor,Total_Credit

FROMstudent;執(zhí)行結(jié)果如圖6-15所示。圖6-15消除重復(fù)行

6.2.2使用數(shù)據(jù)來源——FROM子句FROM子句可以指定SELECT查詢的對(duì)象。第一種方式是使用USE語句讓一個(gè)數(shù)據(jù)庫成為當(dāng)前數(shù)據(jù)庫,F(xiàn)ROM子句中指定的數(shù)據(jù)表名應(yīng)該屬于當(dāng)前數(shù)據(jù)庫,如果要對(duì)多個(gè)表的數(shù)據(jù)進(jìn)行查詢,則后面寫上多個(gè)數(shù)據(jù)表名,數(shù)據(jù)表名間用逗號(hào)分隔。語法格式如下。USE數(shù)據(jù)庫名;SELECT*FROM數(shù)據(jù)表名1,數(shù)據(jù)表名2,…;第二種方式是指定數(shù)據(jù)表名前帶上表所屬數(shù)據(jù)庫的名字。SELECT*FROMdbb.st;6.2.3使用查詢條件——WHERE子句WHERE子句的語法格式如下。WHERE條件條件的格式如下。表達(dá)式<比較運(yùn)算符>表達(dá)式 #比較運(yùn)算|邏輯表達(dá)式<邏輯運(yùn)算符>邏輯表達(dá)式|表達(dá)式[NOT]LIKE表達(dá)式[ESCAPE'esc字符' #LIKE運(yùn)算符|表達(dá)式[NOT][REGEXP|RLIKE]表達(dá)式 #REGEXP運(yùn)算符|表達(dá)式[NOT]BETWEEN表達(dá)式AND表達(dá)式 #指定范圍|表達(dá)式IS[NOT]NULL #是否空值判斷|表達(dá)式[NOT]IN(子查詢|表達(dá)式[,...n]) #IN子句|表達(dá)式<比較運(yùn)算符>{ALL|SOME|ANY}(子查詢) #比較子查詢|EXIST(子查詢) #EXIST子查詢6.2.3使用查詢條件——WHERE子句1.比較運(yùn)算比較運(yùn)算符用于比較兩個(gè)表達(dá)式值,當(dāng)兩個(gè)表達(dá)式值均不為空值時(shí),比較運(yùn)算返回邏輯值TRUE(真)或FALSE(假);而當(dāng)兩個(gè)表達(dá)式值中有一個(gè)為空值或都為空值時(shí),將返回UNKNOWN。MySQL支持的比較運(yùn)算符有:=(等于)、<(小于)、<=(小于等于)、>(大于)、>=(大于等于)、<=>(相等或都等于空)、<>(不等于)、!=(不等于)?!纠?-16】查詢數(shù)據(jù)庫ssms表student中學(xué)號(hào)為201101的學(xué)生的情況。SELECTName,S_ID,Total_Credit

FROMstudent

WHERES_ID=201101;

執(zhí)行結(jié)果如圖6-16所示。圖6-16學(xué)號(hào)為201101的學(xué)生的情況6.2.3使用查詢條件——WHERE子句【例6-17】查詢表student中總學(xué)分大于50分的學(xué)生的情況。SELECTName,S_ID,Birthday,Total_Credit

FROMstudent

WHERETotal_Credit>50;

執(zhí)行結(jié)果如圖6-17所?示。圖6-17總學(xué)分大于50分的學(xué)生的情況【例6-18】查詢表student中專業(yè)為信息安全,性別為女(Sex=0)的學(xué)生的情況,SELECTName,S_ID,Major,sex,Total_Credit

FROMstudent

WHEREMajor='信息安全'ANDSex=0;圖6-18表student中專業(yè)為信息安全,性別為女的學(xué)生的情況6.2.3使用查詢條件——WHERE子句2.模式匹配(1)LIKE運(yùn)算符LIKE運(yùn)算用于指出一個(gè)字符串是否與指定的字符串相匹配,其運(yùn)算對(duì)象可以是CHAR、VARCHAR、TEXT、DATETIME等類型的數(shù)據(jù),返回邏輯值TRUE或FALSE。LIKE運(yùn)算符的語法格式如下。表達(dá)式[NOT]LIKE表達(dá)式[ESCAPE'esc字符’]使用LIKE運(yùn)算符進(jìn)行模式匹配時(shí),常使用特殊符號(hào)“_”和“%”進(jìn)行模糊查詢?!?”代表0個(gè)或多個(gè)字符,“_”代表單個(gè)字符?!纠?-19】查詢數(shù)據(jù)庫ssms表student中姓“王”的學(xué)生的學(xué)號(hào)、姓名及性別。SELECTName,S_ID,sex

FROMstudent

WHERENameLIKE'王%';

執(zhí)行結(jié)果如圖6-19所示。圖6-19表student中姓“王”的學(xué)生6.2.3使用查詢條件——WHERE子句【例6-20】查詢數(shù)據(jù)庫ssms表student中,學(xué)號(hào)倒數(shù)第二個(gè)數(shù)字為0的學(xué)生的學(xué)號(hào)、姓名及專業(yè)。SELECTName,S_ID,Major

FROMstudent

WHERES_IDlike'%0_';【例6-21】查詢數(shù)據(jù)庫ssms表student中名字包含下劃線的學(xué)生的學(xué)號(hào)和姓名。SELECTName,S_ID,Major

FROMstudent

WHERES_IDLIKE'%#_%'ESCAPE'#';執(zhí)行結(jié)果如圖6-20所?示。圖6-20學(xué)號(hào)倒數(shù)第二個(gè)數(shù)字為0的學(xué)生由于沒有學(xué)生滿足這個(gè)條件,所以這里沒有結(jié)果返回。6.2.3使用查詢條件——WHERE子句(2)REGEXP運(yùn)算符REGEXP運(yùn)算符用來執(zhí)行更復(fù)雜的字符串比較運(yùn)算。REGEXP是正則表達(dá)式的縮寫,但它不是SQL標(biāo)準(zhǔn)的一部分。REGEXP運(yùn)算符的一個(gè)同義詞是RLIKE。REGEXP運(yùn)算符的語法格式如下。表達(dá)式[NOT][REGEXP|RLIKE]表達(dá)式表6-2REGEXP運(yùn)算符的特殊字符的含義6.2.3使用查詢條件——WHERE子句【例6-22】查詢姓“王”的學(xué)生的學(xué)號(hào)、姓名和專業(yè)。SELECTName,S_ID,Major

FROMstudent

WHERENameREGEXP'^王';執(zhí)行結(jié)果如圖6-21所?示。圖6-21姓“王”的學(xué)生的學(xué)號(hào)、姓名和專業(yè)【例6-23】查詢學(xué)號(hào)包含5、6、7的學(xué)生的學(xué)號(hào)、姓名和專業(yè)。SELECTName,S_ID,Major

FROMstudent

WHERES_IDREGEXP'[5,6,7]';執(zhí)行結(jié)果如圖6-22所?示。圖6-22學(xué)號(hào)里包含5、6、7的學(xué)生6.2.3使用查詢條件——WHERE子句【例6-24】查詢學(xué)號(hào)以“20”開頭,以“18”結(jié)尾的學(xué)生的學(xué)號(hào)、姓名和專業(yè)。SELECTName,S_ID,Major

FROMstudent

WHERES_IDREGEXP'^20.*18$';執(zhí)行結(jié)果如圖6-23所示。圖6-23學(xué)號(hào)以20開頭,以18結(jié)尾的學(xué)生6.2.3使用查詢條件——WHERE子句3.范圍比較用于范圍比較的關(guān)鍵字有兩個(gè):BETWEEN和IN。①當(dāng)要查詢的條件是某個(gè)范圍時(shí),可以使用關(guān)鍵字BETWEEN指出查詢范圍,其語法格式如下。表達(dá)式[NOT]BETWEEN表達(dá)式1AND表達(dá)式2②使用關(guān)鍵字IN可以指定一個(gè)值表,值表中列出所有可能的值,當(dāng)表達(dá)式與值表中的任意一個(gè)值匹配時(shí),即返回TRUE,否則返回FALSE。使用關(guān)鍵字IN指定值表的語法格式如下。表達(dá)式IN(表達(dá)式1[,…表達(dá)式n])6.2.3使用查詢條件——WHERE子句【例6-25】查詢數(shù)據(jù)庫ssms表student中2003年出生的學(xué)生情況。SELECTS_ID,Name,Major,Birthday

FROMstudent

WHEREBirthdayBETWEEN'2003-01-01'AND'2003-12-31';執(zhí)行結(jié)果如圖6-24所示。圖6-24

2003年出生的學(xué)生6.2.3使用查詢條件——WHERE子句【例6-26】查詢表student中專業(yè)為“信息安全”或“軟件工程”的學(xué)生的情況。SELECT*

FROMstudent

WHEREMajorIN('信息安全','軟件工程');上述語句與如下語句等價(jià)。SELECT*

FROMstudent

WHEREMajor='信息安全'ORMajor='軟件工程';6.2.3使用查詢條件——WHERE子句4.空值比較當(dāng)需要判定一個(gè)表達(dá)式的值是否為空值時(shí),可使用關(guān)鍵字ISNULL,其語法格式如下。表達(dá)式IS[NOT]NULL【例6-27】查詢表student中有備注(備注不為空)的學(xué)生的情況。SELECT*

FROMstudent

WHERENoteISNOTNULL;

執(zhí)行結(jié)果如圖6-25所示。圖6-25表student中備注不為空的學(xué)生的情況6.2.4使用分組——GROUPBY子句GROUPBY子句主要用于根據(jù)字段對(duì)記錄進(jìn)行分組。其語法格式如下。GROUPBY{列名|表達(dá)式}[ASC|DESC],…[WITHROLLUP]該子句可以根據(jù)一個(gè)或多個(gè)列進(jìn)行分組,也可以根據(jù)表達(dá)式進(jìn)行分組,經(jīng)常和聚合函數(shù)一起使用。GROUPBY子句可以在列的后面指定ASC(升序)或DESC(降序)。ROLLUP指定在結(jié)果集內(nèi)不僅包含正常行,還包含匯總行。執(zhí)行結(jié)果如圖6-26所?示。圖6-26各專業(yè)及其學(xué)生人數(shù)【例6-28】查詢各專業(yè)及其學(xué)生數(shù)。SELECTMajor,COUNT(*)AS'學(xué)生人數(shù)'FROMstudentGROUPBYMajor;6.2.4使用分組——GROUPBY子句【例6-29】求被選修的各門課程的平均成績和選修該課程的人數(shù)。SELECTC_ID,avg(Grade)AS'平均成績',COUNT(S_ID)AS'選修人數(shù)'FROMelectiveGROUPBYC_ID;圖6-27被選修的各門課程的平均成績和選修該課程的人數(shù)執(zhí)行結(jié)果如圖6-27所示。6.2.4使用分組——GROUPBY子句【例6-30】查詢每個(gè)專業(yè)的男生人數(shù)、女生人數(shù)、總?cè)藬?shù)以及學(xué)生總?cè)藬?shù)。SELECTMajor,Sex,COUNT(*)AS'人數(shù)'FROMstudentGROUPBYMajor,SexWITHROLLUP;執(zhí)行結(jié)果如圖6-28所?示。圖6-28每個(gè)專業(yè)的男生人數(shù)、女生人數(shù)、總?cè)藬?shù)以及學(xué)生總?cè)藬?shù)不帶ROLLUP關(guān)鍵字的GROUPBY子句如下。SELECTMajor,Sex,COUNT(*)AS'人數(shù)'FROMstudentGROUPBYMajor,Sex;圖6-29不帶ROLLUP關(guān)鍵字的GROUPBY子句執(zhí)行結(jié)果如圖6-29所示。6.2.4使用分組——GROUPBY子句【例6-31】在數(shù)據(jù)庫ssms上產(chǎn)生一個(gè)結(jié)果集,包括各門課程各專業(yè)的平均成績、每門課程的總平均成績和所有課程的總平均成績。SELECTC_Name,Major,AVG(Grade)AS'平均成績'FROMstudent,course,electiveWHEREstudent.S_ID=elective.S_IDANDelective.C_ID=course.C_IDGROUPBYC_Name,MajorWITHROLLUP;圖6-30各門課程各專業(yè)的平均成績、每門課程的總平均成績和所有課程的總平均成績執(zhí)行結(jié)果如圖6-30所示。6.2.5使用分組條件——HAVING子句使用HAVING子句的目的與WHERE子句類似,不同的是WHERE子句用來在FROM子句之后選擇行,而HAVING子句用來在GROUPBY子句之后選擇行。其語法格式如下。HAVING條件條件的定義和WHERE子句中的條件類似,不過HAVING子句中的條件可以包含聚合函數(shù),而WHERE子句則不可以。SQL標(biāo)準(zhǔn)要求HAVING子句必須引用GROUPBY子句中的列或用于聚合函數(shù)中的列。MySQL允許HAVING子句引用SELECT查詢結(jié)果中的列和外部子查詢中的列。6.2.5使用分組條件——HAVING子句【例6-32】查詢平均成績?cè)?5分及以上的學(xué)生的學(xué)號(hào)和平均分。SELECTS_ID,AVG(Grade)AS'平均分'FROMelectiveGROUPBYS_IDHAVINGAVG(Grade)>=85;圖6-31平均成績?cè)?5分及以上的學(xué)生執(zhí)行結(jié)果如圖6-31所示。6.2.5使用分組條件——HAVING子句【例6-33】查詢選修課程超過兩門且成績都在85分及以上的學(xué)生的學(xué)號(hào)。SELECTS_IDFROMelectiveWHEREGrade>=85GROUPBYS_IDHAVINGCOUNT(*)>2;圖6-32選修課程超過兩門且成績都在85分及以上的學(xué)生的學(xué)號(hào)執(zhí)行結(jié)果如圖6-32所示。6.2.5使用分組條件——HAVING子句【例6-34】查詢軟件工程專業(yè)平均成績?cè)?0分以上的學(xué)生的學(xué)號(hào)和平均成績。SELECTS_ID,AVG(Grade)AS'平均成績'FROMelectiveWHERES_IDIN(SELECTS_IDFROMstudentWHEREMajor='軟件工程')GROUPBYS_IDHAVINGAVG(Grade)>80;圖6-33軟件工程專業(yè)平均成績?cè)?0分以上的學(xué)生的學(xué)號(hào)和平均成績執(zhí)行結(jié)果如圖6-27所示。6.2.6使用排序——ORDERBY子句使用SELECT語句查詢出來的數(shù)據(jù)可能是無序的,如果不使用ORDERBY子句,則結(jié)果中行的順序不一定是用戶所期望的。使用ORDERBY子句后可以保證結(jié)果中的行按一定順序排列。ORDERBY子句的語法格式如下。ORDERBY{列名1|表達(dá)式1|順序號(hào)1}[ASC|DESC],{列名2|表達(dá)式2|順序號(hào)2}[ASC|DESC]…在上面的語法格式中,指定的列名1、列名2等是查詢結(jié)果排序的依據(jù)。在排序過程中,先按照列名1進(jìn)行排序,如果列名1的值相同,則按照列名2進(jìn)行排序。參數(shù)ASC表示按照升序進(jìn)行排列,DESC表示按照降序排列。默認(rèn)情況下,按照ASC方式排序。6.2.6使用排序——ORDERBY子句【例6-35】將軟件工程專業(yè)的學(xué)生按出生日期的先后排序。SELECTS_ID,Name,Major,BirthdayFROMstudentWHEREMajor='軟件工程'ORDERBYBirthday;圖6-34軟件工程專業(yè)的學(xué)生按出生日期的先后排序執(zhí)行結(jié)果如圖6-34所示。6.2.6使用排序——ORDERBY子句【例6-36】將信息安全專業(yè)學(xué)生的高等數(shù)學(xué)課程成績按降序排列。SELECTName,C_Name,Major,GradeFROMstudent,elective,courseWHEREstudent.S_ID=elective.S_IDANDelective.C_ID=course.C_IDANDMajor='信息安全'ANDC_Name='高等數(shù)學(xué)'ORDERBYGradeDESC;圖6-35信息安全專業(yè)學(xué)生高等數(shù)學(xué)課程成績降序排列執(zhí)行結(jié)果如圖6-35所示。6.2.6使用排序——ORDERBY子句【例6-37】將信息安全專業(yè)學(xué)生按平均成績升序排列。SELECTS_ID,Name,MajorFROMstudentWHEREMajor='信息安全'OrderBy(SELECTAVG(Grade)FROMelectiveGROUPBYelective.S_IDHAVINGstudent.S_ID=elective.S_ID);圖6-36信息安全專業(yè)學(xué)生按平均成績升序排列執(zhí)行結(jié)果如圖6-36所示。6.2.7使用輸出行限制——LIMIT子句LIMIT子句主要用于限制SELECT語句返回的記錄數(shù)。LIMIT子句的語法格式如下。LIMIT后面可以跟兩個(gè)參數(shù)。第一個(gè)參數(shù)用于表示偏移量,如果偏移量為0,則從查詢結(jié)果的第一條記錄開始返回,偏移量為1,則從查詢結(jié)果的第二條記錄開始返回,以此類推。如果不指定,則其默認(rèn)值為0。第二個(gè)參數(shù)“行數(shù)”表示返回查詢記錄的條數(shù)。LIMIT{[偏移量,]行數(shù)}6.2.7使用輸出行限制——LIMIT子句【例6-38】查詢表student中學(xué)號(hào)最小的前5位學(xué)生的信息。SELECT*FROMstudentORDERBYS_IDLIMIT5;圖6-37表student中學(xué)號(hào)最小的前5位學(xué)生的信息執(zhí)行結(jié)果如圖6-37所示。6.2.7使用輸出行限制——LIMIT子句【例6-39】查詢表student中總學(xué)分排名第4至第8名的學(xué)生信息。SELECT*FROMstudentORDERBYTotal_CreditDESCLIMIT3,5;圖6-38表student中總學(xué)分排名第4至第8名的學(xué)生執(zhí)行結(jié)果如圖6-38所示。使用多表查詢實(shí)現(xiàn)數(shù)據(jù)查詢6.3如果要在兩個(gè)或兩個(gè)以上表中查詢數(shù)據(jù),則必須在FROM子句中指定多個(gè)表來進(jìn)行關(guān)聯(lián)查詢。將兩個(gè)或兩個(gè)以上表中不同列的數(shù)據(jù)組合到一個(gè)表中叫作表的連接。根據(jù)查詢方式的不同,關(guān)聯(lián)查詢可以分為多表連接查詢和多表聯(lián)合查詢,其中多表連接查詢包括交叉連接、內(nèi)連接和外連接。6.3.1使用交叉連接指定了關(guān)鍵字CROSSJOIN的連接是交叉連接。交叉連接即笛卡兒乘積,是指兩個(gè)表中所有元組的任意組合。交叉連接的語法格式如下。SELECT列名1,…FROM表1CROSSJOIN表2;在不包含連接條件時(shí),交叉連接結(jié)果表是由第一個(gè)表的每一行與第二個(gè)表的每一行拼接后形成的,因此結(jié)果表的行數(shù)等于兩個(gè)表的行數(shù)之積。6.3.1使用交叉連接【例6-40】列出學(xué)生所有可能的選課情況。SELECTS_ID,Name,C_ID,C_NameFROMstudentCROSSJOINcourse;圖6-39學(xué)生所有可能的選課情況執(zhí)行結(jié)果如圖6-39所示。6.3.2使用內(nèi)連接指定了關(guān)鍵字INNER的連接是內(nèi)連接。使用內(nèi)連接時(shí),如果兩個(gè)表的相關(guān)列滿足連接條件,就從這兩個(gè)表中提取數(shù)據(jù)并組合成新的記錄。也就是在內(nèi)連接查詢中,只有滿足條件的數(shù)據(jù)才能出現(xiàn)在結(jié)果關(guān)系中。內(nèi)連接的語法格式如下。SELECT列名1,…FROM表1[INNER]JOIN表2ON表1.列名=表2.列名;內(nèi)連接是系統(tǒng)默認(rèn)的,可以省略關(guān)鍵字INNER。使用內(nèi)連接后,F(xiàn)ROM子句中的ON條件主要用來連接表,其他并不屬于連接表的條件可以使用WHERE子句來指定。內(nèi)連接可以沒有連接條件,也就是可以沒有ON之后的內(nèi)容,這時(shí)系統(tǒng)會(huì)保留所有結(jié)果。6.3.2使用內(nèi)連接【例6-41】查詢數(shù)據(jù)庫ssms中所有學(xué)生選過的課程及其課程號(hào)。SELECTDISTINCTcourse.C_Name,elective.C_IDFROMcourseINNERJOINelectiveONcourse.C_ID=elective.C_ID;圖6-40所有學(xué)生選過的課程及其課程號(hào)執(zhí)行結(jié)果如圖6-40所示。6.3.2使用內(nèi)連接【例6-42】查詢選修了課程206且成績?cè)?0分及以上的學(xué)生的姓名及成績。SELECTName,GradeFROMstudentINNERJOINelectiveONstudent.S_ID=elective.S_IDWHEREC_ID='206'ANDGrade>=80;圖6-41選修了課程206且成績?cè)?0分及以上的學(xué)生執(zhí)行結(jié)果如圖6-41所示。6.3.2使用內(nèi)連接【例6-43】查詢選修了計(jì)算機(jī)基礎(chǔ)課程且成績?cè)?0分及以上的學(xué)生的學(xué)號(hào)、姓名、課程及成績。SELECTstudent.S_ID,Name,C_Name,GradeFROMstudentJOINelectiveONstudent.S_ID=elective.S_IDJOINcourseONelective.C_ID=course.C_IDWHEREC_Name='計(jì)算機(jī)基礎(chǔ)'ANDGrade>=80;圖6-42選修了計(jì)算機(jī)基礎(chǔ)課程且成績?cè)?0分及以上的學(xué)生執(zhí)行結(jié)果如圖6-42所示。6.3.2使用內(nèi)連接【例6-44】查詢與黃飛同學(xué)專業(yè)相同的學(xué)生的信息。SELECTa.S_ID,a.Name,a.MajorFROMstudentASaJOINstudentASbONa.Major=b.MajorWHEREb.Name='黃飛';圖6-43與黃飛同學(xué)專業(yè)相同的學(xué)生的信息執(zhí)行結(jié)果如圖6-43所示。6.3.2使用內(nèi)連接【例6-45】查詢數(shù)據(jù)庫ssms中課程不同、成績相同的學(xué)生的學(xué)號(hào)、課程號(hào)和成績。SELECTa.S_ID,a.C_ID,b.C_ID,a.GradeFROMelectiveASaJOINelectiveASbONa.S_ID=b.S_IDANDa.Grade=b.GradeANDa.C_ID!=b.C_ID;圖6-44課程不同、成績相同的學(xué)生執(zhí)行結(jié)果如圖6-44所示。6.3.2使用內(nèi)連接【例6-46】查詢表course中所有學(xué)生選過的課程。SELECTDISTINCTC_NameFROMcourseINNERJOINelectiveUSING(C_ID);圖6-45表course中所有學(xué)生選過的課程執(zhí)行結(jié)果如圖6-45所示。6.3.2使用內(nèi)連接【例6-47】查詢數(shù)據(jù)庫ssms中所有學(xué)生選過的課程及其課程號(hào)。SELECTDISTINCTcourse.C_Name,elective.C_IDFROMcourse,electiveWHEREcourse.C_ID=elective.C_ID;本例語句完全等價(jià)于如下語?句。SELECTDISTINCTcourse.C_Name,elective.C_IDFROMcourseINNERJOINelectiveONcourse.C_ID=elective.C_ID;6.3.3使用外連接指定了關(guān)鍵字OUTER的連接為外連接,其中關(guān)鍵字OUTER可省略。外連接是只限制一個(gè)表中的數(shù)據(jù)必須滿足連接條件,而另一個(gè)表中的數(shù)據(jù)可以不滿足連接條件的連接方式。外連接的語法格式如下。SELECT列名1,…FROM表1{LEFT|RIGHT|FULL}[OUTER]JOIN表2ON表1.列名=表2.列名;外連接包括以下幾種。①左外連接(LEFTOUTERJOIN):結(jié)果表中除了匹配行,還包括左表(表1)有,但右表(表2)中不匹配的行,對(duì)于這樣的行,右表(表2)被選擇的列設(shè)置為NULL。②右外連接(RIGHTOUTERJOIN):結(jié)果表中除了匹配行,還包括右表(表2)有,但左表(表1)中不匹配的行,對(duì)于這樣的行,左表(表1)被選擇的列設(shè)置為NULL。③全外連接(FULLOUTERJOIN):結(jié)果表中除了匹配行,還包括左表(表1)和右表(表2)中不匹配的行,對(duì)于這樣的行,兩個(gè)表被選擇的列設(shè)置為NULL。6.3.3使用外連接【例6-48】查詢所有學(xué)生情況及他們選修的課程號(hào),若學(xué)生未選修任何課程,則結(jié)果中也要包括其情況。SELECTstudent.*,C_ID,GradeFROMstudentLEFTOUTERJOINelectiveONstudent.S_ID=elective.S_ID;圖6-46所有學(xué)生情況及他們選修的課程號(hào)執(zhí)行結(jié)果如圖6-46所示。6.3.3使用外連接【例6-49】查詢被選修了的課程的情況和所有開設(shè)的課程。SELECTelective.*,C_NameFROMelectiveRIGHTOUTERJOINcourseONelective.C_ID=course.C_ID;圖6-47被選修了的課程的情況和所有開設(shè)的課程執(zhí)行結(jié)果如圖6-47所示。6.3.4使用聯(lián)合查詢使用UNION語句,可以把許多SELECT語句返回的結(jié)果組合到一個(gè)結(jié)果集合中。例如,要查詢兩個(gè)學(xué)校的學(xué)生信息,就需要從甲學(xué)校查詢學(xué)生信息,再從乙學(xué)校查詢學(xué)生信息,然后將兩次的查詢結(jié)果合并。UNION語句的語法格式如下。SELECT…UNION[ALL|DISTINCT]SELECT…[UNION[ALL|DISTINCT]SELECT…;SELECT語句為常規(guī)的選擇語句,但是還必須遵守以下規(guī)則。①位于每個(gè)SELECT語句對(duì)應(yīng)位置的被選擇的列,應(yīng)具有相同的數(shù)目和類型。例如,被第一個(gè)語句選擇的第一列應(yīng)當(dāng)和被其他語句選擇的第一列具有相同的類型。②只有最后一個(gè)SELECT語句可以使用INTOOUTFILE。③HIGHPRIORITY不能與作為UNION一部分的SELECT語句同時(shí)使用。④ORDERBY和LIMIT子句只能在整個(gè)語句的最后指定,同時(shí)還應(yīng)對(duì)單個(gè)的SELECT語句加上圓括號(hào)。排序和限制行數(shù)對(duì)整個(gè)最終結(jié)果起作用。6.3.4使用聯(lián)合查詢【例6-50】在表student中查詢學(xué)號(hào)為201101的學(xué)生信息和在表student_copy中查詢學(xué)號(hào)為20201101的學(xué)生信息。SELECTS_ID,Name,Sex,Major

FROMstudent

WHERES_ID='201101'UNIONSELECTS_ID,Name,Sex,Major

FROMstudent_copy

WHERES_ID='20201101';圖6-48聯(lián)合查詢結(jié)果執(zhí)行結(jié)果如圖6-48所示。使用子查詢實(shí)現(xiàn)數(shù)據(jù)查詢6.46.4.1使用帶關(guān)鍵字IN的子查詢關(guān)鍵字IN用于判斷一個(gè)給定值是否在子查詢結(jié)果集中,語法格式如下。表達(dá)式[NOT]IN(子查詢)圖6-49選修課程102的學(xué)生執(zhí)行結(jié)果如圖6-49所示。【例6-51】在數(shù)據(jù)庫ssms中查詢選修了課程102的學(xué)生的學(xué)號(hào)、姓名。SELECTS_ID,Name

FROMstudent

WHERES_IDIN

(SELECTS_ID

FROMelective

WHEREC_ID='102'

);6.4.1使用帶關(guān)鍵字IN的子查詢【例6-52】查詢未選修計(jì)算機(jī)基礎(chǔ)課程的學(xué)生的學(xué)號(hào)、姓名、專業(yè)。SELECTS_ID,Name,MajorFROMstudentWHERES_IDnotIN(SELECTS_IDFROMelectiveWHEREC_IDIN(SELECTC_IDFROMcourseWHEREC_Name='計(jì)算機(jī)基礎(chǔ)'));圖6-50未選修計(jì)算機(jī)基礎(chǔ)課程的學(xué)生執(zhí)行結(jié)果如圖6-50所示。6.4.2使用帶關(guān)鍵字EXISTS的子查詢關(guān)鍵字EXISTS用于測(cè)試子查詢的結(jié)果集是否為空,若子查詢的結(jié)果集不為空,則返回TRUE,否則返回FALSE。EXISTS還可與NOT結(jié)合使用,即NOTEXISTS,其返回值與EXIST剛好相反。EXISTS子查詢的語法格式如下。[NOT]EXISTS(subquery)6.4.2使用帶關(guān)鍵字EXISTS的子查詢【例6-53】查詢選修課程206的學(xué)生姓名。SELECTNameFROMstudentWHEREEXISTS(SELECT*FROMelectiveWHERES_ID=student.S_IDANDC_ID='206');圖6-51選修課程206的學(xué)生執(zhí)行結(jié)果如圖6-51所示。6.4.2使用帶關(guān)鍵字EXISTS的子查詢【例6-54】查詢選修了全部課程的學(xué)生的姓名。SELECTName

FROMstudent

WHERENOTEXISTS(SELECT*FROMcourseWHERENOTEXISTS(SELECT*FROMelectiveWHERES_ID=student.S_IDANDC_ID=course.C_ID));6.4.2使用帶關(guān)鍵字EXISTS的子查詢【例6-55】從表student中查詢總學(xué)分大于50分的男同學(xué)的學(xué)號(hào)和姓名。SELECTS_ID,Name,Total_CreditFROM(SELECT*FROMstudentWHERETotal_Credit>50)ASstdWHERESex=1;圖6-52總學(xué)分大于50分的男同學(xué)的學(xué)號(hào)和姓名執(zhí)行結(jié)果如圖6-52所示。6.4.2使用帶關(guān)鍵字EXISTS的子查詢【例6-56】從表student中查詢所有女學(xué)生的學(xué)號(hào)、姓名,以及學(xué)分差(與平均學(xué)分的差距)。SELECTS_ID,Name,Sex,Total_Credit-(SELECTAVG(Total_Credit)FROMstudent)AS學(xué)分差

FROMstudentWHERESex=0;圖6-53所有女學(xué)生的學(xué)號(hào)、姓名,以及學(xué)分差執(zhí)行結(jié)果如圖6-53所示。6.4.2使用帶關(guān)鍵字EXISTS的子查詢【例6-57】查詢與201101號(hào)學(xué)生性別相同、總學(xué)分相同的學(xué)生的學(xué)號(hào)和姓名。SELECTS_ID,Name,Sex,Total_CreditFROMstudentWHERE(Sex,Total_Credit)=(SELECTSex,Total_CreditFROMstudentWHERES_ID='201101');圖6-54與201101號(hào)學(xué)生性別相同、總學(xué)分相同的學(xué)生執(zhí)行結(jié)果如圖6-54所示。6.4.3使用帶比較運(yùn)算符的子查詢?nèi)绻梢源_認(rèn)子查詢返回的結(jié)果只包含一個(gè)單值,那么可以直接使用比較運(yùn)算符連接子查詢。這可使表達(dá)式的值與子查詢的結(jié)果進(jìn)行比較運(yùn)算,語法格式如下。表達(dá)式{<|<=|=|>|>=|!=|<>}(子查詢)6.4.3使用帶比較運(yùn)算符的子查詢【例6-58】查詢選修了高等數(shù)學(xué)課程的學(xué)生的學(xué)號(hào)。SELECTS_IDFROMelectiveWHEREC_ID=(SELECTC_IDFROMcourseWHEREC_Name='高等數(shù)學(xué)');圖6-55選修了高等數(shù)學(xué)課程的學(xué)生執(zhí)行結(jié)果如圖6-55所示。6.4.3使用帶比較運(yùn)算符的子查詢【例6-59】查詢總學(xué)分高于平均學(xué)分的學(xué)生的學(xué)號(hào)、姓名和總學(xué)分。SELECTS_ID,Name,Total_CreditFROMstudentWHERETotal_Credit>(SELECTAVG(Total_Credit)FROMstudent);圖6-56總學(xué)分高于平均學(xué)分的學(xué)生執(zhí)行結(jié)果如圖6-56所示。6.4.4使用帶關(guān)鍵字ANY、SOME的子查詢ANY和SOME是同義詞,表示表達(dá)式只要與子查詢結(jié)果集中的某個(gè)值滿足比較的關(guān)系,就返回TRUE,否則返回FALSE。語法格式如下。表達(dá)式{<|<=|=|>|>=|!=|<>}{ANY|SOME}(子查詢)表6-3ANY、SOME與比較運(yùn)算符結(jié)合使用時(shí)的用法6.4.4使用帶關(guān)鍵字ANY、SOME的子查詢【例6-60】查詢表elective中課程206的成績不低于課程101的最低成績的學(xué)生的學(xué)號(hào)。SELECTS_ID

FROMelective

WHEREC_ID='206'ANDGrade>=any(SELECTGradeFROMelectiveWHEREC_ID='101');圖6-57課程206的成績不低于課程101的最低成績的學(xué)生執(zhí)行結(jié)果如圖6-57所示。6.4.4使用帶關(guān)鍵字ANY、SOME的子查詢【例6-61】查詢黃飛同學(xué)選修的課程。SELECTC_NameFROMcourseWHEREC_ID=any(SELECTC_IDFROMelectiveWHERES_ID=(SELECTS_IDFROMstudentWHEREName='黃飛'));圖6-58黃飛同學(xué)選修的課程執(zhí)行結(jié)果如圖6-58所示。6.4.5使用帶關(guān)鍵字ALL的子查詢關(guān)鍵字ALL指定表達(dá)式要與子查詢結(jié)果集中的每個(gè)值都進(jìn)行比較,只有表達(dá)式與每個(gè)值都滿足比較的關(guān)系時(shí),才返回TRUE,否則返回FALSE。其語法格式如下。表達(dá)式{<|<=|=|>|>=|!=|<>}{ALL}(子查詢)如果子查詢的結(jié)果集只返回一行數(shù)據(jù),則可以通過比較運(yùn)算符直接比較;若返回多行數(shù)據(jù),則必須使用關(guān)鍵字ALL或ANY。關(guān)鍵字ALL一般也與比較運(yùn)算符結(jié)合使用,如表6-4所示。表6-4ALL與比較運(yùn)算符結(jié)合使用時(shí)的用法6.4.5使用帶關(guān)鍵字ALL的子查詢【例6-62】查詢表student中比信息安全專業(yè)所有學(xué)生年齡都大的學(xué)生的學(xué)號(hào)、姓名、專業(yè)、出生日期。SELECTS_ID,Name,Major,Birthday

FROMstudent

WHEREBirthday<ALL(SELECTBirthdayFROMstudentWHEREMajor='信息安全');圖6-59比信息安全專業(yè)所有學(xué)生年齡都大的學(xué)生執(zhí)行結(jié)果如圖6-59所示?!拘〗Y(jié)】本項(xiàng)目主要講解了聚合函數(shù)、單表數(shù)據(jù)查詢、多表連接查詢和子查詢。其中單表數(shù)據(jù)查詢、多表連接查詢和子查詢是數(shù)據(jù)庫操作中比較重要的內(nèi)容,特別是多表連接查詢和子查詢。通過本項(xiàng)目的學(xué)習(xí),希望讀者能夠熟練掌握相關(guān)知識(shí),并多加練習(xí),為以后項(xiàng)目的學(xué)習(xí)打下堅(jiān)實(shí)基礎(chǔ)?!局R(shí)拓展】1.什么是文氏圖?文氏圖有什么作用?文氏圖(Venndiagram)是用封閉曲線表示集合及其關(guān)系的圖形,主要用于描述集合間的關(guān)系及其運(yùn)算,有直觀、形象、信息量大且富有啟發(fā)性的特點(diǎn)。SQL的JOIN連接可以通過文氏圖解釋,它能很清楚地表明各種連接關(guān)系,主要有內(nèi)連接、左外連接和右外連接。假設(shè)A表和B表各有4條記錄,其中有兩條記錄是相同的,如表6-5和表6-6所示?!局R(shí)拓展】用文氏圖表示3種不同的連接方式,分別如圖6-60~圖6-62所示。【知識(shí)拓展】2.如何優(yōu)化SELECT語句?(1)不要使用SELECT*FROMA任何地方都不要使用SELECT*FROMA,要用具體的字段列表代替“*”,不要返回用不到的任何字段。(2)為每個(gè)表設(shè)置一個(gè)ID主鍵每個(gè)表都應(yīng)該設(shè)置一個(gè)ID主鍵,最好是一個(gè)INT型的,并且設(shè)置自動(dòng)增加的AUTO_INCREMENT標(biāo)志,這點(diǎn)其實(shí)應(yīng)該是設(shè)計(jì)表結(jié)構(gòu)要做的第一件事。(3)避免在WHERE子句中用!=或<>運(yùn)算符應(yīng)盡量避免在WHERE子句中使用!=或<>運(yùn)算符,否則引擎將放棄使用索引而進(jìn)行全表掃描。(4)WHERE子句使用IN或NOTIN的優(yōu)化SQL語句中盡量少用IN或NOTIN,使用IN或者NOTIN會(huì)丟棄索引,從而進(jìn)行全盤掃描,示例如?下。SELECTidFROMAWHEREnumIN(1,2,3);【知識(shí)拓展】對(duì)于連續(xù)的數(shù)值,可用BETWEEN…AND替換IN,以優(yōu)化查詢。SELECTidFROMAWHEREnumISNULL;SELECTidFROMAWHEREnumBETWEEN1AND3;(5)WHERE子句使用OR的優(yōu)化通常使用UNIONALL或UNION替換OR會(huì)得到更好的效果。WHERE子句中使用了關(guān)鍵字OR,索引將被放棄使用,示例如下。SELECTidFROMAWHEREnum=10ORnum=20;可使用UNIONALL或UNION替換OR優(yōu)化查詢。SELECTidFROMAWHEREnum=10UNIONALLallSELECTidFROMAWHEREnum=20;(6)WHERE子句中使用ISNULL或ISNOTNULL的優(yōu)化在WHERE子句中使用ISNULL或ISNOTNULL,索引將被放棄使用,會(huì)進(jìn)行全表查詢,示例如下。【知識(shí)拓展】ISNULL在實(shí)際業(yè)務(wù)場(chǎng)景下使用率極高,但應(yīng)注意避免全表掃描,可以優(yōu)化成在num上設(shè)置默認(rèn)值0,確保表中num沒有null值。SELECTidFROMAWHEREEXISTS(SELECT*FROMBWHEREid>=3000ANDA.id=B.id);SELECTidFROMAWHEREnum=0;(7)使用內(nèi)連接來替換子查詢子查詢的性能相對(duì)比內(nèi)連接低,應(yīng)盡量用內(nèi)連接來替換子查?詢。一個(gè)字段的標(biāo)簽同時(shí)在主查詢和WHERE子句中的查詢中出現(xiàn),那么很可能當(dāng)主查詢中的字段值改變之后,子查詢必須重新進(jìn)行一次。查詢嵌套層次越多,效率越低,因此應(yīng)當(dāng)盡量避免使用子查詢。如果子查詢不可避免,那么應(yīng)在子查詢中過濾掉盡可能多的行。例如,應(yīng)用子查詢的代碼如下。優(yōu)化后的代碼如下。SELECTidFROMAINNERJOINBONA.id=B.idWHEREb.id>=3000;也可以優(yōu)化成如下代碼。SELECTidFROMA,BWHEREA.id=B.idANDb.id>=3000;【知識(shí)拓展】INSERTINTOA(name,age)VALUES('A',24);INSERTINTOA(name,age)VALUES('B',24);INSERTINTOA(name,age)VALUES('C',24);(8)批量插入優(yōu)化批量插入多個(gè)數(shù)據(jù)時(shí),應(yīng)盡量避免一條語句只插入一行數(shù)據(jù),插入3條記錄的代碼如下。優(yōu)化后的代碼如下。INSERTINTOA(name,age)VALUES('A',24),('B',24),('C',24);【任務(wù)訓(xùn)練6】實(shí)現(xiàn)圖書管理系統(tǒng)數(shù)據(jù)庫中的數(shù)據(jù)查詢1.實(shí)驗(yàn)?zāi)康恼莆誗ELECT語句的基本用法。掌握使用聚合函數(shù)進(jìn)行數(shù)據(jù)查詢的方法。掌握并靈活運(yùn)用子查詢。掌握多表查詢的方法。2.實(shí)驗(yàn)內(nèi)容?完成圖書管理系統(tǒng)數(shù)據(jù)庫中的數(shù)據(jù)查詢。3.實(shí)驗(yàn)步驟(1)運(yùn)用SELECT語句在數(shù)據(jù)庫bms中進(jìn)行數(shù)據(jù)查詢

①查詢表bookinfo中的所有數(shù)?據(jù)。USEbms;SELECT*FROMbookinfo;【任務(wù)訓(xùn)練3】創(chuàng)建與管理圖書管理系統(tǒng)數(shù)據(jù)庫②查詢讀者的借閱證號(hào)、姓名、電話。SELECTcard_id,name,tel

FROMreaderinfo;SELECTbook_name,author,pressFROMbookinfoWHEREbook_id='20150202';執(zhí)行結(jié)果如圖6-63所?示。③查詢圖書編號(hào)為20150202的圖書的書名、作者、出版社信息。執(zhí)行結(jié)果如圖6-64所示。圖6-63讀者的借閱證號(hào)、姓名、電話圖6-64圖書編號(hào)為20150202的圖書的信息【任務(wù)訓(xùn)練3】創(chuàng)建與管理圖書管理系統(tǒng)數(shù)據(jù)庫④查詢表readerinfo中男性讀者的年齡和電話,使用AS子句將結(jié)果中各列的標(biāo)題分別指定為“年齡”和“電話”。SELECTAGEAS年齡,telAS電話

FROMreaderinfoWHEREsex='男';執(zhí)行結(jié)果如圖6-65所?示。圖6-65男性讀者的年齡和電話【任務(wù)訓(xùn)練3】創(chuàng)建與管理圖書管理系統(tǒng)數(shù)據(jù)庫⑤查詢表readerinfo中讀者的姓名和性別,要求sex字段值為“男”時(shí)顯示“男士”,為“女”時(shí)顯示“女士”。SELECTnameAS姓名,CASEWHENsex='男'THEN'男士'WHENsex='女'THEN'女士'ENDAS性別

FROMreaderinfo;執(zhí)行結(jié)果如圖6-66所?示。圖6-66讀者的姓名和性別【任務(wù)訓(xùn)練3】創(chuàng)建與管理圖書管理系統(tǒng)數(shù)據(jù)庫⑥計(jì)算每本書的殘值(殘值為書價(jià)格的80%)。SELECTbook_id,book_name,price*0.8AS殘值

FROMbookinfo;執(zhí)行結(jié)果如圖6-68所示。圖6-67每本書的殘值執(zhí)行結(jié)果如圖6-67所示。⑦統(tǒng)計(jì)讀者的總?cè)藬?shù)。SELECTCOUNT(*)AS讀者總數(shù)

FROMreaderinfo;圖6-68讀者的總?cè)藬?shù)【任務(wù)訓(xùn)練3】創(chuàng)建與管理圖書管理系統(tǒng)數(shù)據(jù)庫(2)使用子查詢?cè)跀?shù)據(jù)庫bms中進(jìn)行數(shù)據(jù)查詢①查詢王鵬的借閱信息。SELECT*

FROMborrowinfo

WHEREcard_id=(SELECTcard_id

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論