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