3.使用子查詢?cè)L問和修改數(shù)據(jù)
子查詢和連接查詢1樣提供了使用單個(gè)查詢?cè)L問多個(gè)表中的數(shù)據(jù)的方法。子查詢?cè)谄渌Y(jié)果的基礎(chǔ)上提供1種有效地方式來表示W(wǎng)HERE子句的條件。子查詢是1個(gè)SELECT語(yǔ)句,它定義在SELECT、INSERT、UPDATE或DELECT語(yǔ)句或另外一個(gè)子查詢中。子查詢的SELECT語(yǔ)句可與外部查詢指向不同的表。
嵌套的子查詢或嵌套的SELECT語(yǔ)句是指包括1個(gè)或多個(gè)子查詢的SELECT語(yǔ)句。子查詢可嵌套在外部的SELECT、INSERT、UPDATE或DELECT語(yǔ)句的WHERE或HAVING子句或其他子查詢內(nèi)。如果嵌套了多層,則總是首先評(píng)估最內(nèi)層的查詢。子查詢同樣成為內(nèi)查詢,也能夠嵌套任意數(shù)量的子查詢。任何可使用表達(dá)式的地方都可使用子查詢,只要它返回的是單個(gè)值。
3.1返回多行的子查詢
子查詢是在SELECT語(yǔ)句中的WHERE子句實(shí)現(xiàn)的,可以把WHERE子句中的子查詢分成兩類:返回多行的子查詢和只返回1個(gè)值的子查詢。
3.1.1使用IN關(guān)鍵字
可使用IN關(guān)鍵字來判斷1個(gè)表中指定列的值是不是包括在已定義的列表中,或在另外一個(gè)表中。在前1種情況下,可以指定列名、IN關(guān)鍵字和用來指定列進(jìn)行比較的值列表;在后1種情況下,可以指定列名、IN關(guān)鍵字和援用另外1個(gè)表的子查詢。
舉例來講,從數(shù)據(jù)庫(kù)”銷售管理系統(tǒng)“中,查詢(沒有)接待過顧客的業(yè)務(wù)員的相干信息。
SELECT 業(yè)務(wù)員姓名,家庭住址,電話
FROM 業(yè)務(wù)員信息
WHERE 業(yè)務(wù)員編號(hào) (NOT)IN
( SELECT 所屬業(yè)務(wù)員編號(hào)
FROM 客戶信息 )
3.1.2使用EXISTS關(guān)鍵字
在1些情況下,只需要返回1個(gè)真值或假值。EXISTS關(guān)鍵字只重視子查詢是不是返回行。如果子查詢返回1個(gè)或多個(gè)行,那末EXISTS便返回為真,否則為假。子查詢必須是1個(gè)真實(shí)的值,它用來比較不同表中兩列的值。
使用EXISTS關(guān)鍵字引入1個(gè)子查詢時(shí),就相當(dāng)于進(jìn)行1次是不是存在的測(cè)試。它的作用是在WHERE子句中測(cè)試子查詢返回的行是不是存在。EXISITS子查詢實(shí)際上不產(chǎn)生任何數(shù)據(jù),它只返回TRUE或FALSE。
舉例來講,在數(shù)據(jù)庫(kù)”銷售管理系統(tǒng)“中,查詢”供應(yīng)商信息“表中,”供應(yīng)商編號(hào)“為1006的供應(yīng)商所提供的商品的相干信息。
SELECT 商品名稱,產(chǎn)地,單價(jià)
FROM 商品信息
WHERE EXISITS
(SELECT *
FROM 供應(yīng)商信息
WHERE 供應(yīng)商編號(hào)=商品信息.供應(yīng)商編號(hào)
AND 供應(yīng)商編號(hào)=1006)
NOT EXISTS和EXISTS相反,如果子查詢沒有返回行,則滿足NOT EXISTS中的WHERE子句,即在子查詢返回行時(shí),NOT EXISTS查詢成功。
舉例來講,在”珠寶銷售系統(tǒng)“中,查詢?cè)凇变N售信息“中沒有提供珠寶并且其所在城市不是北京市的珠寶商的相干信息,并按”珠寶商所在城市“進(jìn)行排序。
SELECT 珠寶商姓名,珠寶商地址,珠寶商所在城市,電話
FROM 珠寶商信息
WHERE NOT EXISTS
(SELECT *
FROM 銷售信息
WHERE 珠寶商編號(hào)=珠寶商信息.珠寶商編號(hào)
)
AND 珠寶商所在城市<>'北京市'
ORDER BY 珠寶商所在城市
3.1.3使用比較運(yùn)算符
子查詢可以由1個(gè)比較運(yùn)算符引入。與使用關(guān)鍵字IN引入的子查詢1樣,由比較運(yùn)算符與1些關(guān)鍵字引入的子查詢返回1個(gè)值列表。
SQL支持的在子查詢中使用到的比較運(yùn)算符有ANY、SOME和ALL。ANY和SOME關(guān)鍵字只重視是不是有返回值滿足搜索條件,它們的含義相同,可以相互替換使用。ALL關(guān)鍵字只重視是不是所有的返回值都滿足搜索條件。
舉例來講,在數(shù)據(jù)庫(kù)”銷售管理系統(tǒng)“的”出庫(kù)單明細(xì)信息“表中,查詢”出庫(kù)商品金額“大于任意1個(gè)”入庫(kù)單明細(xì)信息“表中”入庫(kù)商品金額“高于10000的出庫(kù)單的相干信息。
SELECT *
FROM 出庫(kù)單明細(xì)信息
WHERE 出庫(kù)單商品金額 > ANY
(SELECT 入庫(kù)商品金額
FROM 入庫(kù)單明細(xì)信息
WHERE 入庫(kù)商品金額 > 10000)
為了方便學(xué)習(xí)二者使用情況,我們進(jìn)行對(duì)照學(xué)習(xí),下面就舉1個(gè)相同的例子,在數(shù)據(jù)庫(kù)”銷售管理系統(tǒng)“的”出庫(kù)單明細(xì)信息“表中,查詢”出庫(kù)商品金額“大于所有”入庫(kù)單明細(xì)信息“表中”入庫(kù) 商品金額“低于10000的出庫(kù)單的相干信息。
SELECT *
FROM 出庫(kù)單明細(xì)信息
WHERE 出庫(kù)單商品金額 > ALL
(SELECT 入庫(kù)商品金額
FROM 入庫(kù)單明細(xì)信息
WHERE 入庫(kù)商品金額 < 10000)
3.2返回單個(gè)值的子查詢
這樣的子查詢只返回1個(gè)值,然后將1列值與單個(gè)子查詢返回的值進(jìn)行比較,這時(shí)候可使用比較運(yùn)算符。
由未修改的比較運(yùn)算符(后面不跟ANY或ALL的比較運(yùn)算符)引入的子查詢必須返回單個(gè)值而不是值列表。
舉例來講,在”珠寶銷售系統(tǒng)“中,查詢與”消費(fèi)者編號(hào)“為27的消費(fèi)者同處1個(gè)城市的珠寶商相干信息,要求以列”珠寶商姓名“、”珠寶商地址“、”珠寶商所在城市“和”電話“的情勢(shì)返回查詢結(jié)果。
SELECT 珠寶商姓名,珠寶商地址,珠寶山所在城市,電話
FROM 珠寶商信息
WHERE 珠寶商所在城市=
(SELECT 消費(fèi)者所在城市
FROM 顧客信息
WHERE 消費(fèi)者編號(hào)=27
)
由于聚集函數(shù)可以返回1個(gè)單值,所以可以在子好擦尋中包括聚集函數(shù)。
舉例來講,在數(shù)據(jù)庫(kù)”銷售管理系統(tǒng)“中的”商品信息“表中,查詢單價(jià)大于平均價(jià)格的商品的相干信息。要求以列”商品名稱“、”產(chǎn)地“和”單價(jià)“的情勢(shì)返回查詢結(jié)果。
SELECT 商品名稱,產(chǎn)地,單價(jià)
FROM 商品信息
WHERE 單價(jià)>
(SELECT AVG(單價(jià))
FROM 商品信息
)
3.3使用相干子查詢
在之前說明的子查詢中,SQL只對(duì)子查詢進(jìn)行1次評(píng)估,然后替換搜索條件中的子查詢結(jié)果,和根據(jù)搜索條件的值來對(duì)外部查詢進(jìn)行評(píng)估。但是,有些子查詢的履行進(jìn)程依賴于值得外部查詢。結(jié)果是,反復(fù)的履行子查詢,對(duì)外部查詢選擇的每行都履行1次。這樣的子查詢稱為相干子查詢。
由于相干子查詢依賴于其結(jié)果的外部查詢,所以他們不能進(jìn)行單獨(dú)評(píng)估。相干子查詢的WHERE子句援用外部查詢的FROM子句中的表。也就是說,相干子查詢是1個(gè)在外部查詢中包括表的援用外部查詢的FROM子句中的表。也就是說,相干子查詢是1個(gè)在外部插敘中包括表的援用的子查詢,它不能再外部查詢之前求值。
舉例來講,在”銷售管理系統(tǒng)“中,查詢由”供應(yīng)商名稱“為”北京世紀(jì)葵花“提供的商品的相干信息。要求以列”商品名稱“、”產(chǎn)地“和”單價(jià)“的情勢(shì)返回查詢結(jié)果。
SELECT 商品名稱,產(chǎn)地,單價(jià)
FROM 商品信息
WHERE '北京世紀(jì)葵花' IN
(SELECT 供應(yīng)商名稱
FROM 供應(yīng)商信息
WHERE 商品信息.供應(yīng)商編號(hào)=供應(yīng)商信息.供應(yīng)商編號(hào)
)
在相干子查詢中,也能夠?yàn)楸碇付ū砻脛e名來代替表名。但是如果對(duì)同1個(gè)表進(jìn)行相干子查詢時(shí),則必須為表指定別名。
舉例來講,在”珠寶營(yíng)銷系統(tǒng)“的”顧客信息“表中,查詢顧客所居住的不同城市。
SELECT DISTINCT A.消費(fèi)者所在城市
FROM 顧客信息 A
WHERE A.消費(fèi)者所在城市 IN
(SELECT B.消費(fèi)者所在城市
FROM 顧客信息 B
WHERE A.消費(fèi)者編號(hào)<>B.消費(fèi)者編號(hào)
)
上述子查詢的語(yǔ)句同等于下面的自連接查詢語(yǔ)句(關(guān)于自連接的相干介紹,請(qǐng)查閱這里),將該自連接查詢語(yǔ)句運(yùn)行后,其查詢結(jié)果與上述的子查詢語(yǔ)句的結(jié)果完全相同。
SELECT DISTINCT A.消費(fèi)者所在城市
FROM 顧客信息 A INNER JOIN 顧客信息 B
ON A.消費(fèi)者所在城市=B.消費(fèi)者所在城市
AND A.消費(fèi)者編號(hào)<>B.消費(fèi)者編號(hào)
3.4使用嵌套子查詢
前面介紹了只有1個(gè)子查詢的SELECT語(yǔ)句,但是,在SELECT語(yǔ)句中還可以包括多個(gè)子查詢,即1個(gè)子查詢中還包括其它子查詢,這樣的查詢稱為嵌套子查詢。
在SELECT語(yǔ)句中使用多個(gè)子查詢的1種方法是把它們作為這個(gè)語(yǔ)句的不同組成部份。例如,1個(gè)WHERE子句可能含有兩個(gè)關(guān)鍵字來引導(dǎo)兩個(gè)子查詢語(yǔ)句。還有1種在SELECT語(yǔ)句中使用多個(gè)子查詢的方法是把1個(gè)子查詢嵌套到另外一個(gè)子查詢中。
舉例來講,在數(shù)據(jù)庫(kù)“銷售管理系統(tǒng)”中,查詢客戶在2005年6月1日至2005年12月31日之間購(gòu)買商品時(shí),接待客戶的業(yè)務(wù)員的相干信息。要求以列“業(yè)務(wù)員姓名”、“家庭住址”和“電話”的情勢(shì)返回查詢結(jié)果。
SELECT 業(yè)務(wù)員姓名,家庭住址,電話
FROM 業(yè)務(wù)員信息
WHERE 業(yè)務(wù)員編號(hào) IN
(SELECT 所屬業(yè)務(wù)員編號(hào)
FROM 客戶信息
WHERE 客戶編號(hào) IN
(SELECT 客戶編號(hào)
FROM 出庫(kù)單信息
WHERE 出庫(kù)日期 BETWEEN '2005⑹⑴' AND '2005⑴2⑶1'
)
)
上述語(yǔ)句運(yùn)行順序?yàn)椋壕G色部份,紫色部份,藍(lán)色部份,即由內(nèi)到外,逐次查詢。
3.5使用子查詢修改數(shù)據(jù)
子查詢還可以用來修改數(shù)據(jù)庫(kù)中的數(shù)據(jù)。使用子查詢修改數(shù)據(jù)主要是通過下面3個(gè)關(guān)鍵字來實(shí)現(xiàn)INSERT、UPDATE和DELETE。
3.5.1插入數(shù)據(jù)
INSERT語(yǔ)句可以向已有表中添加數(shù)據(jù)。它可以直接向表中插入數(shù)據(jù),也能夠用視圖向隱含表中插入數(shù)據(jù)。如果要在INSERT語(yǔ)句中使用子查詢,必須把它作為VALUES子句中定義的1個(gè)值。
舉例來講,在數(shù)據(jù)庫(kù)“銷售管理系統(tǒng)”中的“業(yè)務(wù)員信息”表中增加1名業(yè)務(wù)員的1行新數(shù)據(jù),該行數(shù)據(jù)中“業(yè)務(wù)員編號(hào)”為1009,“業(yè)務(wù)員姓名”、“家庭住址”和“電話”來自“客戶信息”表中“客戶編號(hào)”為1008的“客戶姓名”、“客戶地址”和“聯(lián)系電話”。
INSERT INTO 業(yè)務(wù)員信息 VALUES
(1009,
(SELECT 客戶姓名
FROM 客戶信息
WHERE 客戶編號(hào)=1008),
(SELECT 客戶地址
FROM 客戶信息
WHERE 客戶編號(hào)=1008),
(SELECT 聯(lián)系電話
FROM 客戶信息
WHERE 客戶編號(hào)=1008)
)
再履行下面語(yǔ)句進(jìn)行查看:SELECT * FROM 業(yè)務(wù)員信息
在INSERT語(yǔ)句中使用子查詢向表中插入數(shù)據(jù)時(shí),必須肯定子查詢的返回結(jié)果只能返回1個(gè)值。如果返回的查詢結(jié)果中多于1個(gè)值,就會(huì)出現(xiàn)毛病,并且子查詢中返回的單個(gè)值必須和目標(biāo)列的數(shù)據(jù)類型及其他限制1致。
3.5.2更新數(shù)據(jù)
UPDATE語(yǔ)句允許修改表中已有數(shù)據(jù)。和INSERT語(yǔ)句1樣,可以直接對(duì)表中的數(shù)據(jù)進(jìn)行修改。如果視圖可更新,也能夠通過視圖進(jìn)行修改。要在UPDATE語(yǔ)句中使用子查詢,子查詢則由WHERE子句引入。
舉例來講,在上個(gè)例子中,將數(shù)據(jù)庫(kù)“銷售管理系統(tǒng)”的“業(yè)務(wù)員信息”表中添加的那1行數(shù)據(jù)所對(duì)應(yīng)的“業(yè)務(wù)員姓名”、“家庭住址”和“電話”分別更改成“趙奇”、“北京市西城區(qū)”和“13585452343”。
UPDATE 業(yè)務(wù)員信息
SET 業(yè)務(wù)員姓名='趙奇',家庭住址='北京市西城區(qū)',電話='13585452343'
WHERE 業(yè)務(wù)員姓名=
(SELECT 客戶姓名
FROM 客戶信息
WHERE 客戶姓名='薛紅林'
)
再履行下面語(yǔ)句進(jìn)行查看:SELECT * FROM 業(yè)務(wù)員信息
3.5.3刪除數(shù)據(jù)
DELETE語(yǔ)句實(shí)現(xiàn)的功能是刪除數(shù)據(jù)庫(kù)表中的數(shù)據(jù)。在DELETE語(yǔ)句中的WHERE子句中使用子查詢與UPDATE語(yǔ)句相似。
舉例來講,將數(shù)據(jù)庫(kù)“銷售管理系統(tǒng)”的“業(yè)務(wù)員信息”表中插入的那1行數(shù)據(jù)刪除。
DELETE 業(yè)務(wù)員信息
WHERE 業(yè)務(wù)員姓名=
(SELECT 客戶姓名
FROM 客戶信息
WHERE 客戶編號(hào)=1008
)
4.學(xué)習(xí)小結(jié)
數(shù)據(jù)庫(kù)的查操作是數(shù)據(jù)庫(kù)的重點(diǎn)學(xué)習(xí)部份,在這幾部份的學(xué)習(xí)和總結(jié)的進(jìn)程中,深感乏力,不管知識(shí)體系的龐大還是其中相干聯(lián)系的撲朔迷離,都是10分重要的,卻也是最難以理解和掌握的。
自己也是用了半月的時(shí)間把數(shù)據(jù)庫(kù)的查操作的總結(jié)用最后的時(shí)間總結(jié)了出來,做1分享,固然,不能不說的是,對(duì)數(shù)據(jù)庫(kù)的相干知識(shí),希望努力去實(shí)踐,在操作中體會(huì)用法,以便更好地掌握其要領(lǐng),也希望自己今后可以做到更好。