第八章子查询本章主要内容8.1前言介绍子查询。8.2检索子查询掌握概念与运用。8.3虚拟表子查询掌握概念与运用。8.4条件子查询掌握概念与运用。8.5总结子查询语法子查询(内查询)在主查询之前一次执行完成。子查询的结果被主查询使用(外查询)。SELECTselect_listFROMtableWHEREexproperator(SELECTselect_listFROMtable);注意事项子查询要包含在括号内。将子查询放在比较条件的右侧。通常情况下不要在子查询中使用ORDERBY子句。单行操作符对应单行子查询,多行操作符对应多行子查询。子查询类型主查询子查询返回单行值•多行子查询多行值主查询子查询返回•单行子查询单行子查询只返回一行。使用单行比较操作符。操作符===含义EqualtoGreaterthanGreaterthanorequaltoLessthanLessthanorequaltoNotequaltoSELECT*FROMTBL_SCOREINFOWHERESCORE=(SELECTMIN(SCORE)FROMTBL_SCOREINFO)在子查询中使用组函数47子查询中的HAVING子句首先执行子查询。向主查询中的HAVING子句返回结果。SELECTCLASSNO,MIN(SCORE)FROMTBL_SCOREINFOGROUPBYCLASSNOHAVINGMIN(SCORE)(SELECTMIN(SCORE)FROMTBL_SCOREINFOWHERECLASSNO='001')47SELECT*FROMTBL_SCOREINFOWHERESCORE=(SELECTMIN(SCORE)FROMTBL_SCOREINFOGROUPBYCLASSNO)非法使用子查询子查询中的空值问题norowsselectedSELECT*FROMTBL_SCOREINFOWHERESCORE=(SELECTMIN(SCORE)FROMTBL_SCOREINFOWHERECLASSNO='004')多行子查询返回多行。使用多行比较操作符。操作符INANYALL含义等于列表中的任何一个和子查询返回的任意一个值比较和子查询返回的所有值比较在多行子查询中使用ANY操作符18.75,12.50,19,17,85SELECT*FROMTBL_BOOKSWHERECOSTANY(SELECTCOSTFROMTBL_BOOKSWHEREPUBID=4);在多行子查询中使用ALL操作符18.75,12.50,19,17,85SELECT*FROMTBL_BOOKSWHERECOSTALL(SELECTCOSTFROMTBL_BOOKSWHEREPUBID=4);子查询中的空值问题SELECT*FROMTBL_BOOKSWHERECOSTNOTIN(SELECTCOSTFROMTBL_BOOKS);norowsselected小结子查询就是在原有的查询语句中,嵌入新的查询,来得到我们想要的结果集。一般根据子查询的嵌入位置分为如下:1.检索子查询2.虚拟表子查询3.条件子查询检索子查询检索子查询就是在我们的SELECT子句中加入完整的查询。例1:检索所有的学生姓名,课程名,考试成绩(关联查询)(参看例8.1)SELECTA.stuname,B.score,C.classnameFROMtbl_studentinfoA,tbl_scoreinfoB,tbl_classinfoCWHEREA.stuno=B.stunoANDB.classno=C.classno检索子查询注意:当使用检索子查询的时候,子查询的结果必须只有一条数据,如果不能保证只有一条数据时,就必须用其他方式限制SELECT(SELECTstunameFROMtbl_studentinfoWHEREstuno=B.stuno),B.score,(SELECTclassnameFROMtbl_classinfoWHEREclassno=B.classno)FROMtbl_scoreinfoB可以用FETCHFIRST1ROWONLY来限制虚拟表子查询虚拟表子查询其实就是在FROM语句中使用子查询的结果集作为一个表。那么在这个临时区域,不论是表数据,还是检索出来的数据都是一个个的结果集。本身没有区别。例1:查询各科成绩最高分(参看例8.4)SELECTMAX(score),classnoFROMtbl_scoreinfoGROUPBYclassno;条件子查询普通子查询:实际上就是在条件中加入查询语句。例:查询张三的计算机成绩(参看例8.6和例8.7)例8.6SELECTC.scoreFROMtbl_studentinfoA,tbl_classinfoB,tbl_scoreinfoCWHEREA.stuno=C.stunoANDB.classno=C.classnoANDA.stuname='张三'ANDB.classname='计算机';条件子查询IN子查询:通常IN子查询表示在某个结果集里面的意思。例:查询考试成绩不及格的学生姓名(参看例8.8)注意:NOTIN子查询。在IN前面可以加上NOT,表示不在这个子查询中存在,就满足这个条件。但是通常NOTIN是效率最低的,所以避免使用。SELECTstunameFROMtbl_studentinfoWHEREstunoIN(SELECTstunoFROMtbl_scoreinfoWHEREscore60);条件子查询EXISTS子查询表示存在某种情况。通常是可以和IN子查询进行互换的。例:查询考试成绩不及格的学生姓名(参看例8.9)SELECTA.stunameFROMtbl_studentinfoAWHEREEXISTS(SELECTstunoFROMtbl_scoreinfoWHEREscore60ANDstuno=A.stuno);条件子查询注意:1.IN和EXISTS子查询可以互换。掌握其互换规则。实际就是IN在子查询外的列放入到EXISTS子查询里面。2.对于EXISTS子查询通常情况下比IN子查询的效率高。所以尽量使用EXISTS子查询。3.和IN,NOTIN相似,EXISTS也有NOTEXISTS子查询,表示不存在某种情况。总结子查询是嵌套在另一个查询的SELECT,FROM,HAVING或WHERE子句中的完整查询。子查询是首先完成的。子查询的结果用作外部查询的输入。单行查询最多可以返回一个值。熟练掌握IN,ALL,ANY,EXISTS的子查询的运算符。