DQL语言学习—数据查询语言
仅作为学习笔记,学习资源来源于B站视频:BV1xW411u7ax
6. 子查询
6.1 含义
嵌套在其他语句内部的select语句称为子查询或内查询,外面的语句可以是insert、update、delete、select等,一般select作为外面语句较多,外面如果为select语句,则此语句称为外查询或主查询
6.2 分类
(1)按出现位置
- select后面:仅支持标量子查询
- from后面:表子查询
- where或having后面: 标量子查询、列子查询、行子查询
- exists后面:标量子查询、列子查询、行子查询、表子查询
(2)按结果集的行列
- 标量子查询(单行子查询):结果集为一行一列
- 列子查询(多行子查询):结果集为多行一列
- 行子查询:结果集为多行多列
- 表子查询:结果集为多行多列
6.3 where或having后面
特点:
- 子查询都放在小括号内
- 子查询一般放在条件的右侧
- 子查询优先于主查询执行,主查询使用了子查询的执行结果
- 标量子查询一般搭配单行操作符使用:> < = <> >= <=
- 列子查询一般搭配多行操作符使用:any、all、in、not in
in: 属于子查询结果中的任意一个就行
any和all往往可以用其他查询代替
(1)标量子查询
#案例1:返回job_id与141号员工相同,salary比141号员工多的员工的姓名、job_id、工资
SELECT last_name,job_id,salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id=141
) AND salary > (
SELECT salary
FROM employees
WHERE employee_id=143
)
#案例2:查询最低工资的员工姓名和工资
# ①最低工资
select min(salary) from employees
# ②查询员工的姓名和工资,要求工资=①
select last_name,salary
from employees
where salary=(
select min(salary) from employees
);
#案例3:查询最低工资大于50号部门最低工资的部门id和其最低工资
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id =50
);
(2)列子查询
#:案例4:查询所有是领导的员工姓名
# ①查询所有员工的 manager_id
select manager_id
from employees
# ②查询姓名,employee_id属于①列表的一个
select last_name
from employees
where employee_id in(
select manager_id
from employees
);
#案例5:返回其它工种中比job_id 为‘IT_PROG’中任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ANY
(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id <> 'IT_PROG';
# 上案例中任一改为所有,则将ANY改为ALL
(3)行子查询
有条件,就是两个查询条件的操作符相同
#案例6:查询员工编号最小并且工资最高的员工信息
SELECT *
FROM employees
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
6.4 select后面
仅仅支持标量子查询
#案例7:查询每个部门的员工个数
**SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.`department_id`
) 个数
FROM departments d;**
6.5 from后面
从查询出的表中进一步查询或者查询的表作为外连接的表进行连接查询
#案例8:查询每个部门的平均工资的工资等级
SELECT ag_dep.*,grade_level
FROM (
SELECT department_id,AVG(salary) 平均工资
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades j
ON ag_dep.平均工资 BETWEEN j.lowest_sal AND j.highest_sal;
#案例9:查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资
#①查询各部门的平均工资
#②连接①结果集和employees表,进行筛选
SELECT employee_id,last_name,salary,e.department_id
FROM employees e
INNER JOIN (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
ON e.department_id = ag_dep.department_id
WHERE salary>ag_dep.ag ;
6.6 exists后面(相关子查询)
exists返回布尔值,判断查询的内容中是否有值。
#案例10:查询有员工的部门名
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.`department_id`=e.`department_id`
);
# 用in做
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
SELECT department_id
FROM employees
);