Copyright©SysTopCorporation,2005.Allrightsreserved.子查询6-2目标通过本章学习,您将可以:•描述子查询可以解决的问题•定义子查询。•列句子查询的类型。•书写单行子查询和多行字查询。6-3使用子查询解决问题谁的工资比Abel高?谁的工资比Abel高?MainQuery:?Abel的工资是多少??Subquery6-4子查询语法•子查询(内查询)在主查询之前一次执行完成。•子查询的结果被主查询使用(外查询)。SELECTselect_listFROMtableWHEREexproperator(SELECTselect_listFROMtable);6-5SELECTlast_nameFROMemployeesWHEREsalary(SELECTsalaryFROMemployeesWHERElast_name='Abel');子查询110006-6注意事项•子查询要包含在括号内。•将子查询放在比较条件的右侧。•除非进行Top-N分析,否则不要在子查询中使用ORDERBY子句。•单行操作符对应单行子查询,多行操作符对应多行子查询。6-7子查询类型MainquerySubqueryreturnsST_CLERK•多行子查询ST_CLERKSA_MANMainquerySubqueryreturns•单行子查询6-8单行子查询•只返回一行。•使用单行比较操作符。Operator===MeaningEqualtoGreaterthanGreaterthanorequaltoLessthanLessthanorequaltoNotequalto6-9SELECTlast_name,job_id,salaryFROMemployeesWHEREjob_id=(SELECTjob_idFROMemployeesWHEREemployee_id=141)ANDsalary(SELECTsalaryFROMemployeesWHEREemployee_id=143);执行单行子查询ST_CLERK26006-10SELECTlast_name,job_id,salaryFROMemployeesWHEREsalary=(SELECTMIN(salary)FROMemployees);在子查询中使用组函数25006-11子查询中的HAVING子句•首先执行子查询。•向主查询中的HAVING子句返回结果。SELECTdepartment_id,MIN(salary)FROMemployeesGROUPBYdepartment_idHAVINGMIN(salary)(SELECTMIN(salary)FROMemployeesWHEREdepartment_id=50);25006-12SELECTemployee_id,last_nameFROMemployeesWHEREsalary=(SELECTMIN(salary)FROMemployeesGROUPBYdepartment_id);非法使用子查询ERRORatline4:ORA-01427:single-rowsubqueryreturnsmorethanonerow6-13子查询中的空值问题norowsselectedSELECTlast_name,job_idFROMemployeesWHEREjob_id=(SELECTjob_idFROMemployeesWHERElast_name='Haas');6-14多行子查询•返回多行。•使用多行比较操作符。OperatorINANYALLMeaningEqualtoanymemberinthelistComparevaluetoeachvaluereturnedbythesubqueryComparevaluetoeveryvaluereturnedbythesubquery6-15在多行子查询中使用ANY操作符9000,6000,4200SELECTemployee_id,last_name,job_id,salaryFROMemployeesWHEREsalaryANY(SELECTsalaryFROMemployeesWHEREjob_id='IT_PROG')ANDjob_id'IT_PROG';…6-16SELECTemployee_id,last_name,job_id,salaryFROMemployeesWHEREsalaryALL(SELECTsalaryFROMemployeesWHEREjob_id='IT_PROG')ANDjob_id'IT_PROG';在多行子查询中使用ALL操作符9000,6000,42006-17子查询中的空值问题SELECTemp.last_nameFROMemployeesempWHEREemp.employee_idNOTIN(SELECTmgr.manager_idFROMemployeesmgr);norowsselected6-18SELECTa.last_name,a.salary,a.department_id,b.salavgFROMemployeesa,(SELECTdepartment_id,AVG(salary)salavgFROMemployeesGROUPBYdepartment_id)bWHEREa.department_id=b.department_idANDa.salaryb.salavg;在FROM子句中使用子查询6-19EXISTS操作符•EXISTS操作符检查在子查询中是否存在满足条件的行•如果在子查询中存在满足条件的行:–不在子查询中继续查找–条件返回TRUE•如果在子查询中不存在满足条件的行:–条件返回FALSE–继续在子查询中查找6-20SELECTemployee_id,last_name,job_id,department_idFROMemployeesouterWHEREEXISTS(SELECT'X'FROMemployeesWHEREmanager_id=outer.employee_id);EXISTS操作符应用举例6-21SELECTdepartment_id,department_nameFROMdepartmentsdWHERENOTEXISTS(SELECT'X'FROMemployeesWHEREdepartment_id=d.department_id);NOTEXISTS操作符应用举例6-22相关更新使用相关子查询依据一个表中的数据更新另一个表的数据UPDATEtable1alias1SETcolumn=(SELECTexpressionFROMtable2alias2WHEREalias1.column=alias2.column);6-23DELETEFROMtable1alias1WHEREcolumnoperator(SELECTexpressionFROMtable2alias2WHEREalias1.column=alias2.column);相关删除使用相关子查询依据一个表中的数据删除另一个表的数据6-24DELETEFROMemployeesEWHEREemployee_id=(SELECTemployee_idFROMemp_historyWHEREemployee_id=E.employee_id);相关删除应用举例6-25总结通过本章学习,您已经学会:•在什么时候遇到什么问题应该使用子查询。•在查询是基于未知的值时应使用子查询。SELECTselect_listFROMtableWHEREexproperator(SELECTselect_listFROMtable);6-26总结通过本章学习,您已经可以:•使用多列子查询•单列子查询•EXISTS和NOTEXISTS操作符•相关更新和相关删除