文/向沖 陳誠
SQL語言是目前數(shù)據(jù)庫領(lǐng)域中非常實(shí)用、流行的主流語言。SQL是Structure Query Language的英文縮寫,意思是結(jié)構(gòu)化查詢語言。包括:數(shù)據(jù)查詢 (SQL)、數(shù)據(jù)操縱 (DML)、數(shù)據(jù)定義 (DDL)和數(shù)據(jù)控制 (DCL)等功能于一體。數(shù)據(jù)查詢是數(shù)據(jù)庫的核心內(nèi)容,也是我們最常用的操作。數(shù)據(jù)查詢是通過SQL語句來實(shí)現(xiàn)的,利用SQL語句可以從數(shù)據(jù)庫中查詢出我們所需要的各種數(shù)據(jù)。[1]
數(shù)據(jù)查詢分為單表查詢和多表查詢。單表查詢是對一個(gè)表的查詢,因?yàn)楸容^簡單,這里不再說明。多表查詢是對多個(gè)表,將分布在不同表中的數(shù)據(jù)根據(jù)需要進(jìn)行查詢。多表查詢可以通過連接查詢和嵌套查詢來實(shí)現(xiàn)。[2]下面以學(xué)生管理數(shù)據(jù)庫為例,介紹以上兩種查詢。其中學(xué)生表和成績表的關(guān)系模式如下:學(xué)生 (學(xué)號,姓名,性別,出生日期,籍貫,班級代碼);成績 (學(xué)號,課程號,成績)。
1.1.1 定義。根據(jù)各個(gè)表之間的邏輯關(guān)系從兩個(gè)或多個(gè)表中查詢數(shù)據(jù)。如:查詢學(xué)生的學(xué)號、姓名、課程名稱和成績,涉及到的數(shù)據(jù)表有學(xué)生、課程和成績。
1.2.1 內(nèi)連接。內(nèi)連接 (inner join)是一種最常用的連接類型。內(nèi)連接是一種任意條件的查詢,如果兩個(gè)表的相關(guān)字段滿足連接條件,就從這兩個(gè)表中提取數(shù)據(jù)并組合成新的記錄,也就是在內(nèi)連接查詢中,只有滿足條件的元組才能出現(xiàn)在結(jié)果關(guān)系中。[3]
例如:要查詢每個(gè)已經(jīng)選課的學(xué)生的情況,查詢語句為:
SELECT*FROM學(xué)生INNER JOIN成績ON學(xué)生.學(xué)號=成績.學(xué)號
連接查詢根據(jù)比較方式分為:
1.2.1.1 等值連接:使用等號 (=)運(yùn)算符比較被連接的列的列值,稱為等值連接。
1.2.1.2 不等連接:使用除等于運(yùn)算符以外的其它比較運(yùn)算符比較被連接的列的列值,稱為不等連接。包括>、>=、<=、<、!>、!<和<>等運(yùn)算符。
1.2.1.3 自然連接:使用等于 (=)運(yùn)算符比較被連接列的列值,但刪除連接表中的重復(fù)列,稱為自然連接。它屬于等值連接的一種特殊情況。
1.2.2 外連接。外連接是指將不滿足限制條件的表中的數(shù)據(jù)也顯示在最終結(jié)果中。
根據(jù)限制表的不同,外連接分為三種情況:
1.2.2.1 左外連接 (LEFTOUTER JOIN)
左外連接是限制連接條件右邊的表中的數(shù)據(jù)必須滿足連接條件,而不關(guān)左邊的表中的數(shù)據(jù)是否滿足連接條件,均輸出左邊表中的內(nèi)容。
例如:要查詢所有學(xué)生的選課情況,包括已經(jīng)選課的和還沒有選課的學(xué)生,查詢語句為:
SELECT學(xué)生.學(xué)號,姓名,班級代碼,課程號,成績
FROM學(xué)生LEFT OUTER JOIN成績ON學(xué)生.學(xué)號=成績.學(xué)號
左外連接查詢中左邊表中的所有元組的信息都得到了保留。
1.2.2.2 右外連接 (RIGHTOUTERJOIN)。右外連接與左外連接類似,只是右端表中的所有元組都列出,限制左端表的數(shù)據(jù)必須滿足連接條件,而不管右端表中的數(shù)據(jù)是否滿足連接條件,均輸出表中的內(nèi)容。
例如:同上例內(nèi)容,查詢語句為
SELECT學(xué)生.學(xué)號,姓名,班級代碼,課程號,成績
FROM學(xué)生RIGHTOUTERJOIN成績ON學(xué)生.學(xué)號=成績.學(xué)號
右外連接查詢中右邊表中的所有元組的信息都得到了保留。
1.2.2.3 全外連接 (FULL OUTER JOIN)。全外連接查詢的特點(diǎn)是左、右兩端表中的元組都輸出,如果沒能找到匹配的元組,就使用NULL來代替。
例如:同左外連接例子內(nèi)容,查詢語句為:
SELECT學(xué)生.學(xué)號,姓名,班級代碼,課程號,成績
FROM學(xué)生FULL OUTER JOIN成績ON學(xué)生.學(xué)號=成績.學(xué)號
全外連接查詢中所有表中的元組信息都得到了保留。
1.2.3 自連接。在同一個(gè)表內(nèi)進(jìn)行自身連接,這種查詢稱為自連接查詢,自連接必須為表指定兩個(gè)別名。
例如:要求檢索出和劉鑫同班同學(xué)的信息,查詢語句為:
SELECT學(xué)生.*FROM學(xué)生JOIN學(xué)生AS學(xué)1 ON學(xué)生.班級代碼=學(xué)生1.班級代碼
WHERE學(xué)生1.姓名=‘劉鑫’and學(xué)生1.學(xué)號<>學(xué)生.學(xué)號
1.2.4 交叉連接。交叉連接即笛卡兒乘積,是指兩個(gè)關(guān)系中所有元組的任意組合。一般情況下,交叉查詢是沒有實(shí)際意義的。
例如:如果希望得到學(xué)生和成績兩個(gè)關(guān)系模式的乘積,查詢語句為:
2.1.1 定義。嵌套查詢是指在一個(gè)SELECT語句的WHERE子句中嵌套另一條SELECT語句的查詢,又稱為子查詢。
2.2.1 無關(guān)子查詢。無關(guān)子查詢的執(zhí)行不依賴于外部嵌套。查詢的執(zhí)行過程為:首先執(zhí)行子查詢,子查詢得到的結(jié)果作為外部查詢的條件使用,然后執(zhí)行外部查詢。通常使用比較運(yùn)算符或[NOT]IN關(guān)鍵字。
2.2.1.1 返回一個(gè)值的子查詢。子查詢的返回值只有一個(gè)時(shí),可以使用比較運(yùn)算符如=、<、>、>=、<=、!=等將父查詢和子查詢連接起來。
例如:要求檢索出和劉鑫同班同學(xué)的信息,查詢語句為:
SELECT*FROM學(xué)生WHERE班級代碼=(SELECT班級代碼FROM學(xué)生 WHERE姓名=’劉鑫’)AND姓名<>’劉鑫’
2.2.1.2 返回一組值的子查詢。子查詢的返回值不止一個(gè),而是一個(gè)集合時(shí),可以在比較運(yùn)算符和子查詢之間插入ANY、SOME或ALL關(guān)鍵字。其中等值關(guān)系可以使用IN關(guān)鍵字。
例如:查詢成績高于選修了“計(jì)算機(jī)基礎(chǔ)”課程平均成績的學(xué)生的學(xué)號和姓名。
SELECT 學(xué)生.學(xué)號,學(xué)生.姓名FROM 成績JOIN 學(xué)生ON 學(xué)生.學(xué)號=成績.學(xué)號
JOIN課程 ON成績.課程號=課程.課程號WHERE課程名= '計(jì)算機(jī)基礎(chǔ)'AND
成績 >ANY(SELECT avg(成績)FROM成績,課程WHERE 成績.課程號=課程.課程號and課程名=‘計(jì)算機(jī)基礎(chǔ)’)
2.2.2 相關(guān)子查詢。相關(guān)子查詢是指在子查詢中,子查詢的查詢條件中引用了外層查詢表中的值。執(zhí)行時(shí)先執(zhí)行外部查詢語句,然后根據(jù)外部查詢返回的結(jié)果執(zhí)行內(nèi)部查詢語句。通常使用[NOT]EXISTS關(guān)鍵字。
例如:查詢沒有學(xué)習(xí)任何課程的學(xué)生的學(xué)號和姓名。
SELECT學(xué)號,姓名FROM學(xué)生WHERE NOT EXISTS(SELECT*FROM成績WHERE成績.學(xué)號=學(xué)生.學(xué)號)
從“要求檢索出和劉鑫同班同學(xué)的信息”這個(gè)例子中我們可以看到,使用連接查詢和嵌套查詢實(shí)現(xiàn)該查詢的結(jié)果完全相同。由此我們可以得出這樣一個(gè)結(jié)論:連接查詢和嵌套查詢之間有時(shí)是可以相互替換的,但不是所有情況下都可以互換。下面將分別介紹連接查詢和嵌套查詢的優(yōu)劣。
3.1 連接查詢的優(yōu)勢和劣勢。連接查詢使用簡單,但因?yàn)樵诟鞅磉B接的同時(shí)對所有的條件綜合查詢,所以不易發(fā)現(xiàn)錯(cuò)誤,一旦出錯(cuò),糾錯(cuò)也比較麻煩。另外,連接查詢實(shí)際上是將所有表根據(jù)條件先合并成一個(gè)表。因此在數(shù)據(jù)量很大的情況下,對計(jì)算機(jī)系統(tǒng)的要求較高,需占用更多的系統(tǒng)資源。
3.2 嵌套查詢的優(yōu)勢和劣勢。嵌套查詢是用戶必須清楚每一個(gè)子查詢的結(jié)果及各表之間的邏輯關(guān)系,對用戶要求較高。但嵌套查詢是逐步求解,需要的計(jì)算機(jī)系統(tǒng)開銷較小。
3.3 怎樣合理運(yùn)用連接查詢和嵌套查詢。綜上可以看出,連接查詢和嵌套查詢各自有其優(yōu)勢和劣勢,在實(shí)際查詢過程中到底采用哪種查詢方式,因根據(jù)使用習(xí)慣及對兩種查詢方式的熟練程度確定,也可以混合使用。
綜上所述,查詢的優(yōu)化必須符合以下條件:滿足查詢需求的同時(shí)提高查詢速度,并能減少計(jì)算機(jī)系統(tǒng)開銷為原則。熟練掌握SQL查詢功能及技巧是基礎(chǔ),另外了解每種查詢的優(yōu)劣才能更好的選擇合適的查詢方式。筆者首先介紹了連接查詢和嵌套查詢的定義和分類,然后通過兩者的對比分析,比較了兩者的優(yōu)勢和劣勢,總結(jié)出實(shí)際使用過程中可根據(jù)自身的實(shí)際需求和使用習(xí)慣選擇合適的查詢方式。
[1]王良元,SQ連接、嵌套與混合查詢 [J],電腦學(xué)習(xí),2005
[2]張文雯,SQ嵌套查詢 [J],信息技術(shù),2011
[3]雷琳,SQL查詢語句優(yōu)化的研究[J],武漢船舶職業(yè)技術(shù)學(xué)院,2011