一、含义
嵌套在其他语句内部的select语句称为子查询或内查询,
外部的查询语句可以是insert、update、delete、select等,一般select作为外面语句较多
外部的查询语句如果为select语句,则此语句称为外查询或主查询
二、分类
1、按出现位置
select后面:
仅仅支持标量子查询
from后面:
表子查询
where或having后面:
标量子查询(单行) √
列子查询(多行) √
行子查询
exists后面:
标量子查询
列子查询
行子查询
表子查询
2、按结果集的行列
标量子查询(单行子查询):结果集为一行一列
列子查询(多行子查询):结果集为多行一列
行子查询:结果集为多行多列
表子查询:结果集为多行多列
三、示例
1、select后面
注意:select后面仅仅支持标量子查询
例:查询员工表(employees)员工号(employee_id)=102的部门名(department_id),其中部门名在部门表(departments)中,员工号在员工表中
SELECT (
SELECT department_name,e.department_id
FROM departments d
INNER JOIN employees e
ON d.department_id=e.department_id
WHERE e.employee_id=102
) 部门名;
2、from后面
注意:如果将子查询结果充当一张表,要求必须起别名
#案例:查询员工表(employees)每个部门(department_id)的平均工资(salary)的工资等级(grade_level),其中工资登记在工作表(job_grades)中
①查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
3、where或having后面
⑴ 标量子查询
例1:查询员工表(employess)最低工资(salary)的员工姓名(last_name)和工资
①先查询最低工资
select min(salary) from employees
②后查询员工的姓名和工资,要求工资=①
select last_name,salary
from employees
where salary=(
select min(salary) from employees
);
⑵ 列子查询
例2:查询员工表(employess)所有是领导(manager_id)的员工姓名(last_name)
①查询所有员工的 manager_id
select manager_id
from employees
②查询姓名,employee_id属于①列表的一个
select last_name
from employees
where employee_id in(
select manager_id
from employees
);
⑶ 行子查询(结果集一行多列或多行多列)
例3:查询员工表(employess)员工编号(employee_id)最小并且工资(salary)最高的员工信息
①查询最小的员工编号
SELECT MIN(employee_id)
FROM employees
②查询最高工资
SELECT MAX(salary)
FROM employees
③查询员工信息
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
)AND salary=(
SELECT MAX(salary)
FROM employees
);
4、exists或in后面(相关子查询)
exists语法:
exists(完整的查询语句)
结果: 1或0
例1:查询部门表(departments)有员工的部门名(department_id)
in
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
SELECT department_id
FROM employees
)
exists
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.`department_id`=e.`department_id`
);