子查询
说明:
当一个查询语句中又嵌套了另一个完整的select语句,则被嵌套的select语句称为子查询或内查询,外面的select语句被称为主查询或外查询
分类:
按子查询出现的位置进行分类:
- select后面
(标量子查询)
要求:子查询的结果为单行单列 - from后面
(表子查询)
要求:子查询的结果可以为多行多列 - where或having后面(重点,子查询中百分之八九十都是使用它)
(单行子查询、多行子查询)
要求:子查询的结果必须为单列
特点:
1. 子查询放在条件中,要求必须放在条件的右侧
2. 子查询一般放在小括号中
3. 子查询的执行优先于主查询
4. 单行子查询对应了 单行操作符:> < >= <= = <>
5. 多行子查询对应了 多行操作符:any/some all in - exists后面
(相关子查询)
要求:子查询结果必须为单列
一. where或having后面
单行子查询
#案例一:查询和Zlotkey相同部门的员工姓名和工资
#1. 查询Zlotkey的部门
SELECT department_id
FROM employees
WHERE last_name='Zlotkey';
#2. 根据1查询该部门编号中的员工姓名和工资
SELECT last_name,salary,department_id
FROM employees
WHERE department_id=(
SELECT department_id
FROM employees
WHERE last_name='Zlotkey'
);
#案例二:查询工资比公司平均工资高的员工的员工号、姓名和工资
#1. 查询公司的平均工资
SELECT AVG(salary)
FROM employees
#2. 查询工资比平均工资高的员工的员工号、姓名和工资
SELECT job_id,last_name,salary
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
);
多行子查询
in:判断某字段是否在指定列表内
x in(10,30,50)
any/some:判断某字段的值是否满足其中任意一个
x>any(10,30,50)
all:判断某字段的值是否满足里面所有
x>all(10,30,50)
#案例一:返回location_id是1400或1700的部门中的所有员工姓名
#1. 返回location_id是1400或1700的部门
SELECT department_id
FROM departments
WHERE location_id IN (1400,1700);
#2. 返回location_id是1400或1700的部门中的所有员工姓名
SELECT last_name
FROM employees
WHERE department_id IN(
SELECT department_id
FROM departments
WHERE location_id IN (1400,1700)
);
#案例二:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
#1. 返回job_id为‘IT_PROG’部门的员工工资
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG';
#2. 返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT job_id,last_name,employee_id,salary
FROM employees
WHERE salary<ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
);
#案例三:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary
SELECT job_id,last_name,employee_id,salary
FROM employees
WHERE salary<ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
);
二. select后面
#案例:查询部门编号是50的员工个数
SELECT(
SELECT COUNT(*)
FROM employees
WHERE department_id=50
) 个数;
三. from后面
#案例:查询每个部门的平均工资的工资级别
#1. 查询每个部门的平均工资
SELECT AVG(salary),partment_id
FROM employees
GROUP BY department_id
#2. 将1和sal_grade两表连接查询
SELECT dep_ag.department_id,dep_ag.ag,g.grade
FROM sal_grade g
JOIN (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) dep_ag
ON dep_ag.ag BETWEEN g.min_salary AND g.max_salary;
四. exists后面
#案例一:查询有无名字叫'Abel'的员工信息
SELECT EXISTS(
SELECT *
FROM employees
WHERE last_name='Abel'
) 有无;
#有,结果为1
#无,结果为0