1.子查詢 在查詢條件中,可以使用另一個查詢的結果作為條件的一部分,例如,判定列值是否與某個查詢的結果集中的值相等,作為查詢條件一部分的查詢稱為子查詢。SQL標准允許SELECT多層嵌套使用,用來表示復雜的查詢。子查詢除了可以用在SELECT語句中,還可以用在INSERT、UPDATE及DELETE語句中。子查詢通常與IN、EXIST謂詞及比較運算符結合使用。 2.IN子查詢 IN子查詢用於進行一個給定值是否在子查詢結果集中的判斷,格式為: expression [ NOT ] IN (subquery ) www.2cto.com 其中,subquery是子查詢。當表達式expression與子查詢subquery的結果表中的某個值相等時,IN謂詞返回TRUE,否則返回FALSE;若使用了NOT,則返回的值剛好相反。 例:查找在XSCJ數據庫中選修了課程號為206的課程的學生的姓名、學號。 SELECT 姓名,學號 FROM XS WHERE 學號 IN (SELECT 學號 FROM XS_KC WHERE課程號 = '206' ); 說明:在執行包含子查詢的SELECT語句時,系統先執行子查詢,產生一個結果表,再執行查詢。本例中,先執行子查詢: SELECT 學號 FROM XS_KC WHERE 課程號='206'; 得到一個只含有學號列的表,XS_KC中的每個課程名列值為206的行在結果表中都有一行。再執行外查詢,若XS表中某行的學號列值等於子查詢結果表中的任一個值,則該行就被選擇。 注意:IN子查詢只能返回一列數據。對於較復雜的查詢,可以使用嵌套的子查詢。 例:查找未選修離散數學的學生的姓名、學號、專業名。 SELECT 姓名,學號,專業名 FROM XS WHERE 學號 NOT IN( SELECT學號 FROM XS_KC WHERE課程號 IN (SELECT 課程號 FROM KC WHERE 課程名 ='離散數學')); www.2cto.com 3.比較子查詢 這種子查詢可以認為是IN子查詢的擴展,它使表達式的值與子查詢的結果進行比較運算,格式為: expression { < | <= |= | > | >= | != | <> } { ALL | SOME | ANY } ( subquery ) 其中,expression為要進行比較的表達式,subquery是子查詢。ALL、SOME和ANY說明對比較運算的限制。 如果子查詢的結果集只返回一行數據時,可以通過比較運算符直接比較。 ALL指定表達式要與子查詢結果集中的每個值都進行比較,當表達式與每個值都滿足比較的關系時,才返回TRUE,否則返回FALSE; SOME或ANY是同義詞,表示表達式只要與子查詢結果集中的某個值滿足比較的關系時,就返回TRUE,否則返回FALSE。 例: 查找XS表中比所有計算機系的學生年齡都大的學生學號、姓名、專業名、出生日期。 SELECT 學號, 姓名, 專業名, 出生日期 FROM XS WHERE 出生日期 <ALL ( SELECT出生日期 FROMXS WHERE專業名 ='計算機' ); 4. EXISTS子查詢 EXISTS謂詞用於測試子查詢的結果是否為空表,若子查詢的結果集不為空,則EXISTS返回TRUE,否則返回FALSE。EXISTS還可與NOT結合使用,即NOTEXISTS,其返回值與EXIST剛好相反。格式為: [ NOT ] EXISTS ( subquery ) 例: 查找選修206號課程的學生姓名。 SELECT 姓名 FROM XS WHERE EXISTS ( SELECT * FROM XS_KC WHERE 學號 = XS.學號 AND 課程號 = '206' ); www.2cto.com 本例與前面的子查詢例子不同點是:前面的例子中,內層查詢只處理一次,得到一個結果集,再依次處理外層查詢;而本例的內層查詢要處理多次,因為內層查詢與XS.學號有關,外層查詢中XS表的不同行有不同的學號值。這類子查詢稱為相關子查詢,因為子查詢的條件依賴於外層查詢中的某些值。其處理過程是:首先查找外層查詢中XS表的第一行,根據該行的學號列值處理內層查詢,若結果不為空,則WHERE條件就為真,就把該行的姓名值取出作為結果集的一行;然後再找XS表的第2、3、…行,重復上述處理過程直到XS表的所有行都查找完為止。 說明:由於沒有人選了全部課程,所以結果為空。 5. MySQL區分了4種類型的子查詢:返回一個表的子查詢是表子查詢;返回帶有一個或多個值的一行的子查詢是行子查詢;返回一行或多行,但每行上只有一個值的是列子查詢;只返回一個值的是標量子查詢。從定義上講,每個標量子查詢都是一個列子查詢和行子查詢。上面介紹的子查詢都屬於列子查詢。另外,子查詢還可以用在SELECT語句的其他子句中。表子查詢可以用在FROM子句中,但必須為子查詢產生的中間表定義一個別名。 6. SELECT關鍵字後面也可以定義子查詢。 例:從XS表中查找所有女學生的姓名、學號,以及與081101號學生的年齡差距。 SELECT 學號, 姓名, YEAR(出生日期)-YEAR( ( SELECT 出生日期 FROM XS WHERE 學號='081101' ) ) AS 年齡差距 FROM XS WHERE 性別='0'; 說明:本例中子查詢返回值中只有一個值,所以這是一個標量子查詢。YEAR函數用於取出DATE類型數據的年份。 在WHERE子句中還可以將一行數據與行子查詢中的結果通過比較運算符進行比較。 例: 查找與081101號學生性別相同、總學分相同的學生學號和姓名。 SELECT 學號,姓名 FROM XS WHERE (性別,總學分)=( SELECT 性別,總學分 FROM XS WHERE 學號='081101' ); 7.使用union可以把來自許多SELECT語句的結果組合到一個結果集合中。語法格式如下: SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...] 說明: www.2cto.com SELECT語句為常規的選擇語句,但是還必須遵守以下規則: ● 列於每個SELECT語句的對應位置的被選擇的列應具有相同的數目和類型。例如,被第一個語句選擇的第一列應和被其他語句選擇的第一列具有相同的類型。 ● 只有最後一個SELECT語句可以使用INTO OUTFILE。 ● HIGH_PRIORITY不能與作為UNION一部分的SELECT語句同時使用。 ● ORDER BY和LIMIT子句只能在整個語句最後指定,同時還應對單個的SELECT語句加圓括號。排序和限制行數對整個最終結果起作用。 8. 使用UNION的時候,在第一個SELECT語句中被使用的列名稱被用於結果的列名稱。MySQL自動從最終結果中去除重復行,所以附加的DISTINCT是多余的,但根據SQL標准,在語法上允許采用。要得到所有匹配的行,則可以指定關鍵字ALL。 例:查找學號為081101和學號為081210的兩位同學的信息。 SELECT 學號, 姓名, 專業名, 性別, 出生日期, 總學分 FROM XS WHERE 學號= '081101' UNION SELECT 學號, 姓名, 專業名, 性別, 出生日期, 總學分 FROM XS WHERE學號= '081210'; 9.handler語句 select語句通常用來返回行的一個集合;MySQL還支持另外一個查詢數據庫的語句:handler語句,該語句能夠一行一行的浏覽表中的數據,他並屬於SQL標准,這是MySQL的專用語句,該語句只適用於MyISAM和InnoDB表。 使用該語句要先使用handler open語句打開一個表,再使用handler read語句浏覽打開表的行,浏覽完後使用handler close語句關閉已打開的表 1). 打開一個表 可以使用handler open語句打開一個表。 語法格式為: HANDLER 表名 OPEN [ AS 新表名 ] 說明:若打開表時使用別名,則在其他進一步訪問表的語句也都要使用別名。 2). 浏覽表中的行 handler read語句用於浏覽一個已經打開的表的數據行。 語法格式為: HANDLER表名READ { FIRST |NEXT } [ WHERE where_condition ] [LIMIT ... ] 說明: www.2cto.com ● FIRST | NEXT:這兩個關鍵字是HANDLER語句的讀取聲明,FIRST表示讀取第一行,NEXT表示讀取下一行。 ● WHERE子句:如果想返回符合特定條件的行,可以加一條WHERE子句,這裡的WHERE子句和SELECT語句中的WHERE子句具有相同的功能,但是這裡的WHERE子句中不能包含子查詢、系統內置函數、BETWEEN、LIKE和IN運算符。 ● LIMIT子句:若不使用LIMIT子句,HANDLER語句只取表中的一行數據。若要讀取多行數據,則要添加LIMIT子句。這裡的LIMIT子句和SELECT語句中的LIMIT子句不同。SLECT語句中的LIMIT子句用來限制結果中的行的總數,而這裡的LIMIT子句用來指定HANDLER語句所能獲得的行數。 10. 由於沒有其他的聲明,在讀取一行數據的時候行的順序是由MySQL決定的。如果要按某個順序來顯示,可以通過在HANDLER READ語句中指定索引來實現。 語法格式為: (1)HANDLER 表名 READ 索引名 { = | >= | <= | < } (value1,value2,...) [ WHERE 條件 ] [LIMIT... ] (2)HANDLER表名READ索引名{ FIRST | NEXT | PREV | LAST } [ WHERE條件 ] [LIMIT ... ] 說明: 第一種方式是使用比較運算符為索引指定一個值,並從符合該條件的一行數據開始讀取表。如果是多列索引,則值為多個值的組合,中間用逗號隔開。value1、value2是為索引指定的值。 第二種方式是使用關鍵字讀取行,FIRST表示第一行,NEXT表示下一行,prev表示上一行,last表示最後一行。 11. 關閉打開的表 行讀取完後必須使用handler close語句來關閉表。 語法格式為: HANDLER 表名close www.2cto.com 例: 一行一行地浏覽KC表中的滿足要求的內容,要求第一行為學分大於4的第一行數據。 首先打開表: USEXSCJ;(指定庫,打開xskj庫) handler KC open;(打開kc表) 讀取滿足條件的第一行:handler KC readFIRST WHERE 學分>4; 讀取下一行: handler KC read NEXT; 關閉該表: handler KC close; 作者 tianyazaiheruan