含义:出现在其他语句内部的 SELECT 语句,称为子查询或内查询。内部嵌套了其他 SELECT 语句的查询,称为外查询或主查询。
特点
- 子查询放在小括号内。
 - 子查询一般放在条件的右侧。
 - 子查询的执行优于主查询执行,主查询的条件用到了子查询的结果。
 
分类
出现位置分类
| 位置 | 支持情况 | 
|---|---|
| SELECT 后面 | 标量子查询 | 
| FROM 后面 | 表子查询 | 
| WHERE 或 HAVING 后面 | 标量子查询/列子查询/行子查询(比较少用) | 
| EXISTS 后面 | 表子查询 | 
结果集行列数分类
| 类型 | 结果集 | 
|---|---|
| 标量子查询 | 一行一列 | 
| 列子查询 | 一列多行 | 
| 行子查询 | 一行多列 | 
| 表子查询 | 多行多列 | 
案例
WHERE 或 HAVING 后面
标量子查询
-- 谁的工资币 Abel 高。SELECT*FROMemployeesWHEREsalary > ( SELECT salary FROM employees WHERE last_name = 'Abel' );-- 返回job_id 与 141 号员工相同,salary 比 143 号员工多的员工 姓名、job_id 和 工资。SELECTlast_name,job_id,salaryFROMemployeesWHEREjob_id = ( SELECT job_id FROM employees WHERE employee_id = 141 )AND salary > ( SELECT salary FROM employees WHERE employee_id = 143 );-- 返回公司工资最少的员工的 last_name、job_id、salary。SELECT last_name, job_id, salary FROM employees WHERE salary =( SELECT MIN( salary ) FROM employees );-- 查询最低工资 > 50 号部门最低工资的部门和其最低工资。SELECTMIN( salary ),department_idFROMemployeesGROUP BYdepartment_idHAVINGMIN( salary ) > ( SELECT MIN( salary ) FROM employees WHERE department_id = 50 );
列子查询
一般会使用到几个关键字。
| 关键字 | 含义 | 
|---|---|
| IN/NOT IN | 等于列表中的任意一个 | 
| ANY/SOME | 和子查询返回的某一个值比较 | 
| ALL | 和子查询返回的所有值比较 | 
-- 返回 location_id 是 1400 或 1700 的部门中的所有员工姓名。SELECTlast_nameFROMemployeesWHEREdepartment_id IN ( SELECT DISTINCT department_id FROM departments WHERE location_id IN ( 1400, 1700 ) );SELECTlast_nameFROMemployeesWHEREdepartment_id = any( SELECT DISTINCT department_id FROM departments WHERE location_id IN ( 1400, 1700 ) );-- 返回其他工种中比 job_id 为 IT_PROG 任一工资低的员工名、姓名、job_id、salary。SELECTlast_name,employee_id,job_id,salaryFROMemployeesWHEREsalary < ALL ( SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG' )AND job_id <> 'IT_PROG';SELECTlast_name,employee_id,job_id,salaryFROMemployeesWHEREsalary < ( SELECT MIN(salary) FROM employees WHERE job_id = 'IT_PROG' )AND job_id <> 'IT_PROG';
行子查询
-- 查询员工编号最小并且工资最最高的员工信息。SELECT*FROMemployeesWHEREemployee_id = ( SELECT MIN( employee_id ) FROM employees )AND salary = ( SELECT MAX( salary ) FROM employees );SELECT*FROMemployeesWHERE( employee_id, salary ) = ( SELECT MIN( employee_id ), MAX( salary ) FROM employees );
SELECT 后面
仅支持标量子查询。
-- 查询每个部门的员工个数。SELECTd.*,( SELECT COUNT(*) FROM employees AS e WHERE e.department_id = d.department_id ) AS countFROMdepartments AS d;-- 查询员工号 = 102 的部门名。SELECT( SELECT department_name FROM departments AS d INNER JOIN employees AS e ON d.department_id = e.department_id WHERE e.employee_id = 102 ) AS NAME;
FROM 后面
-- 查询每个部门的平均工资的工资等级。SELECTag_dep.*,g.grade_levelFROM( SELECT AVG( salary ) AS ag, department_id FROM employees GROUP BY department_id ) AS ag_depINNER JOIN job_grades AS g ON ag_dep.ag BETWEEN lowest_salAND highest_sal;
EXISTS 后面
语法:EXISTS(完整的查询语句)。
-- 查询有员工的部门名。SELECTdepartment_nameFROMdepartments AS dWHEREEXISTS ( SELECT * FROM employees AS e WHERE d.department_id = e.department_id );-- 查询没有女朋友的男生信息。SELECTbo.*FROMboys AS boWHEREbo.id NOT IN ( SELECT boyfriend_id FROM beauty );SELECTbo.*FROMboys AS boWHERENOT EXISTS ( SELECT boyfriend_id FROM beauty AS b WHERE bo.id = b.boyfriend_id );
参考:
