子查詢:
用子查詢能解決的問(wèn)題
假想你想要寫一個(gè)查詢來(lái)找出掙錢比陸濤的薪水還多的人。為了解決這個(gè)問(wèn)題,你需要兩個(gè)查詢:一
個(gè)找出陸濤的收入,第二個(gè)查詢找出收入高于陸濤的人。
你可以用組合兩個(gè)查詢的方法解決這個(gè)問(wèn)題,放置一個(gè)查詢到另一個(gè)查詢中。
內(nèi)查詢或子查詢返回一個(gè)值給外查詢或主查詢。使用一個(gè)子查詢相當(dāng)于執(zhí)行兩個(gè)連續(xù)查詢并且用第一個(gè)
查詢的結(jié)果作為第二個(gè)查詢的搜索值。
子查詢語(yǔ)法:
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);
1.子查詢(內(nèi)查詢) 在主查詢之前執(zhí)行一次
2.子查詢的結(jié)果被用于主查詢(外查詢)
首先執(zhí)行子查詢 (內(nèi)查詢) 顯示子查詢返回的值,然后用內(nèi)查詢返回的結(jié)果執(zhí)行外查詢,最后,執(zhí)行整個(gè)查詢 (包括子查詢),顯示相同的結(jié)果。
子查詢可嵌套的位置:
子查詢是一個(gè)SELECT 語(yǔ)句,它是嵌在
另一個(gè) SELECT 語(yǔ)句中的子句。
使用子查詢你可以用簡(jiǎn)單的語(yǔ)句構(gòu)建功能強(qiáng)大的語(yǔ)句。當(dāng)你需要從表中用依賴于表本身的數(shù)據(jù)選擇行時(shí)
它們是非常有用的。
也可以放在
WHERE 子句 HAVING 子句 FROM 子句。
在語(yǔ)法中:
operator 包括比較條件,例如 >、= 或 IN
比較條件分為兩個(gè)種類:?jiǎn)涡羞\(yùn)算符 (>, =, >=, <, <>, <=) 和多行運(yùn)算符 (IN, ANY, ALL)。
子查詢通常涉及一個(gè)嵌套的 SELECT、子-SELECT 或內(nèi) SELECT 語(yǔ)句。字查詢通常執(zhí)行一次。并且它的輸出被用于完成主或外查詢的查詢條件。
另外,子查詢可以被放在 CREATE VIEW 語(yǔ)句中、CREATE TABLE 語(yǔ)句、UPDATE 語(yǔ)句、INSERT 語(yǔ)句的 INTO 子句和 UPDATE 語(yǔ)句的 SET 子句中。
使用子查詢的原則:
1. 子查詢放在圓括號(hào)中
2.將子查詢放在比較條件的右邊, 可以增加可讀性。
在子查詢中的ORDER BY 子句不需要,除非你正在執(zhí)行Top-N 分析。
Oracle8i 以前的版本中,子查詢不包含 ORDER BY 子句。對(duì)一個(gè) SELECT 語(yǔ)句只能用一個(gè) ORDER BY 子句,并且如果指定了它就必須放在主 SELECT 語(yǔ)句的最后。從 Oracle8i 開(kāi)始,ORDER BY 子句可以使用,并且在進(jìn)行 Top-N 分析時(shí)是必須的。
3.在單行子查詢中用單行運(yùn)算符,在多行子查詢中用多行運(yùn)算符,
在子查詢中可以使用兩種比較條件:?jiǎn)涡羞\(yùn)算符和多行運(yùn)算符。
子查詢的個(gè)數(shù):
Oracle 服務(wù)器沒(méi)有強(qiáng)制限制子查詢的數(shù)目;限制只與查詢所需的緩沖區(qū)大小有關(guān)。
子查詢的類型:
1. 單行子查詢:從內(nèi) SELECT 語(yǔ)句只返回一行的查詢
2. 多行子查詢:從內(nèi) SELECT 語(yǔ)句返回多行的查詢
3. 還有多列子查詢:從內(nèi) SELECT 語(yǔ)句返回多列的查詢。
單行子查詢
單行子查詢是從內(nèi)查詢返回一行的查詢。在該子查詢類型中用一個(gè)單行操作符
SELECT last_name, job_id
FROM employees
WHERE job_id =
(SELECT job_id
FROM employees
WHERE employee_id = 141);
SELECT last_name, job_id, salary
FROM employees
WHERE job_id =
(SELECT job_id FROM employees WHERE employee_id = 141) AND salary >(SELECT salary FROM employees WHERE employee_id = 143);
該例子可以由三個(gè)查詢塊組成:外查詢和兩個(gè)內(nèi)查詢。內(nèi)查詢塊首先被執(zhí)行,產(chǎn)生查詢結(jié)果分別為 ST_CLERK 和 2600。然后處理外查詢塊,并且使用內(nèi)查詢的返回值來(lái)完成它的查詢條件。
兩個(gè)內(nèi)查詢返回單個(gè)值 (分別是 ST_CLERK 和 2600),所以這種 SQL 語(yǔ)句被稱為單行子查詢。
注:外和內(nèi)查詢可以從不同的表中取得數(shù)據(jù)。
在子查詢中使用組函數(shù):
SELECT last_name, job_id, salary
FROM employees
WHERE salary =
(SELECT MIN(salary) FROM employees);
你可以從主查詢中顯示數(shù)據(jù),該主查詢使用一個(gè)帶組函數(shù)的單行子查詢。子查詢放在圓括號(hào)中并且放在比較條件的后面。
例子顯示所有其薪水等于最低薪水的雇員的 last name、job ID 和 salary。 MIN 組函數(shù)返回單個(gè)的值 (2500) 給外函數(shù)。
帶子查詢的HAVING 子句:
1.Oracle 服務(wù)器首先執(zhí)行子查詢
2.Oracle 服務(wù)器返回結(jié)果到主查詢的HAVING 子句中
例
找出平均薪水為最低平均薪水的工作崗位。
SELECT job_id, AVG(salary)
FROM employees
GROUP BY job_id
HAVING AVG(salary) = (SELECT MIN(AVG(salary))
FROM employees
GROUP BY job_id);
子查詢錯(cuò)誤
使用子查詢的一個(gè)常見(jiàn)的錯(cuò)誤是單行子查詢返回返回了多行。
SELECT employee_id, last_name
FROM employees
WHERE salary =
(SELECT MIN(salary) FROM employees GROUP BY department_id);
ERROR at line 4:ORA-01427: single-rowsubqueryreturns more thanone rowERROR
子查詢包含一個(gè) GROUP BY 子句,這就暗示該子查詢將返回多行,每個(gè)對(duì)應(yīng)它所找到的一組,在這種情況下,子查詢的結(jié)果將是 4400、6000、2500、4200、7000、17000 和 8300。
外查詢得到子查詢的結(jié)果 (4400、6000、2500、4200、7000、17000、8300) 并且在它的 WHERE 子句中使用這些結(jié)果。WHERE 子句包含一個(gè)等號(hào) (=) 運(yùn)算符,這是一個(gè)單行比較運(yùn)算符,只能使用一個(gè)值。 = 操作符不能接受來(lái)自子查詢的多個(gè)值,并且因此產(chǎn)生錯(cuò)誤。
為了糾正該錯(cuò)誤,改變 = 操作為 IN。
子查詢的另一個(gè)常見(jiàn)問(wèn)題是內(nèi)查詢沒(méi)有返回行。
,子查詢包含一個(gè) WHERE 子句,推測(cè)起來(lái),其目的是找名字為 Haas 的雇員,該語(yǔ)句是正確的,但在執(zhí)行時(shí)選擇無(wú)行返回。
沒(méi)有名叫 Haas 的雇員,所以子查詢無(wú)返回行,外查詢得到子查詢的結(jié)果 (null) 并且在 WHERE 子句中使用該結(jié)果,外查詢找不到一個(gè) job ID 等于 null 的雇員,所以也沒(méi)有行返回。如果一個(gè) job 存在 null 值,也沒(méi)有返回行,因?yàn)楸容^兩個(gè)空值還是空,因此 WHERE 子句的條件不為 true。
多行子查詢:
多行子查詢
子查詢返回多行被稱為多行子查詢。對(duì)多行子查詢要使用多行運(yùn)算符而不是單行運(yùn)算符。多行運(yùn)算符期待多個(gè)值。
例
查找各部門收入為部門最低的那些雇員。
SELECT last_name, salary, department_id
FROM employees
WHERE salary IN (SELECT MIN(salary)
FROM employees
GROUP BY department_id);
內(nèi)查詢先被執(zhí)行,產(chǎn)生一個(gè)查詢結(jié)果,然后主查詢塊處理和使用由內(nèi)查詢返回的值完成它的搜索條件。事實(shí)上,在 Oracle 服務(wù)器看起來(lái)主查詢象是下面這樣:
SELECT last_name, salary, department_id
FROM employees
WHERE salary IN (2500, 4200, 4400, 6000, 7000, 8300, 8600, 17000);
在多行子查詢中使用ANY 運(yùn)算符
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ANY(SELECT salaryFROM employeesWHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';
ANY 運(yùn)算符 (和它的同義詞, SOME 運(yùn)算符) 比較一個(gè)值與一個(gè)子查詢返回的每一個(gè)值。幻燈片中的例子顯示不是 IT 程序員的雇員,并且這些雇員的的薪水少于IT 程序員。掙錢最多的程序員的薪水是 $9,000。
<ANY
2、數(shù)據(jù)庫(kù)導(dǎo)入:imp 用戶名/密碼@實(shí)例名 fromuser=導(dǎo)出時(shí)用的用戶名 touser=用戶名 file=路徑/文件名.dmp