[TOC]
一、子查询的概念
将一条sql语句执行的结果作为另一个sql语句的条件
二、子查询的规则
# 以下是基于对表的增删改查操作的
1.增数据时: insert into 表名 select 子查询
注解: 对一个表插入数据时,插入的数据可以是另外一个sql语句查询结果,但是首先要创建这个表
2.删除数据时: delete from 表名 条件是 select子查询(表不能与delete表相同)
注解: 删除一个表的某些数据时,他的条件是另一个sql查询语句结果
3.查: select 字段 from 表 条件是select子查询
注解: 查询一个表的数据的条件是一个sql语句的执行结果
4.改: update 表 set 字段=值 条件是select子查询(表不能与update表相同)
注解: 更新一个表的数据,他的条件是另一个sql语句的执行结果
三、子查询的实例
# 数据来源:在单表emp下
# 此处显示emp的数据
mysql> select * from emp;
+----+------+------+------+--------+--------+-----------+-----------+
| id | name | sex | age | salary | area | addr | dep |
+----+------+------+------+--------+--------+-----------+-----------+
| 1 | aaa | 男 | 42 | 10.5 | 上海 | 浦东 | 教职部 |
| 2 | bbb | 男 | 38 | 9.4 | 山东 | 济南 | 教学部 |
| 3 | ccc | 女 | 30 | 3 | 江苏 | 张家港 | 教学部 |
| 4 | ddd | 女 | 28 | 2.4 | 广州 | 广东 | 教学部 |
| 5 | eee | 男 | 28 | 2.4 | 江苏 | 苏州 | 教学部 |
| 6 | fff | 男 | 18 | 8.8 | 中国 | 黄浦 | 咨询部 |
| 7 | ggg | 男 | 18 | 8.8 | 安徽 | 宣城 | 教学部 |
| 8 | hhh | 男 | 28 | 9.8 | 安徽 | 巢湖 | 教学部 |
| 9 | iii | 女 | 36 | 1.2 | 安徽 | 芜湖 | 咨询部 |
| 10 | jjj | 男 | 36 | 5.8 | 山东 | 济南 | 教学部 |
| 11 | kkk | 女 | 28 | 1.2 | 山东 | 青岛 | 教职部 |
| 12 | lll | 男 | 30 | 9 | 上海 | 浦东 | 咨询部 |
| 13 | mmm | 男 | 30 | 6 | 上海 | 浦东 | 咨询部 |
| 14 | nnn | 男 | 30 | 6 | 上海 | 浦西 | 教学部 |
| 15 | ooo | 女 | 67 | 2.501 | 上海 | 陆家嘴 | 教学部 |
+----+------+------+------+--------+--------+-----------+-----------+
3.1 案例(基于emp表)
# 题目:每个部门最高薪资的那个人所有信息
1.先创建一个子查询sql(对emp表的部门进行分组,查询每个部门的最高薪资)
select dep,max(salary) from emp group by dep;
mysql> select dep,max(salary) from emp group by dep;
+-----------+-------------+
| dep | max(salary) |
+-----------+-------------+
| 咨询部 | 9 |
| 教学部 | 9.8 |
| 教职部 | 10.5 |
+-----------+-------------+
2.查操作:通过子查询去进行对emp数据的查找(将子查询作为查询每个部门工资最高的员工的所有信息)
select * from emp where (dep,salary) in (select dep,max(salary) from emp group by dep);
mysql> select * from emp where (dep,salary) in (select dep,max(salary) from emp group by dep);
+----+------+------+------+--------+--------+--------+-----------+
| id | name | sex | age | salary | area | addr | dep |
+----+------+------+------+--------+--------+--------+-----------+
| 1 | aaa | 男 | 42 | 10.5 | 上海 | 浦东 | 教职部 |
| 8 | hhh | 男 | 28 | 9.8 | 安徽 | 巢湖 | 教学部 |
| 12 | lll | 男 | 30 | 9 | 上海 | 浦东 | 咨询部 |
+----+------+------+------+--------+--------+--------+-----------+
3.增加数据操作:通过子查询去对一张表进行增加数据操作
1.首先是先创建一张空表
create table t1(dep_name varchar(64), max_salary decimal(5,2));
2.将子查询的结果作为数据添加到t1表里(将子查询的sql语句直接作为t1表的插入数据)
insert into t1 select dep,max(salary) from emp group by dep;
mysql> select * from t1;
+-----------+------------+
| dep_name | max_salary |
+-----------+------------+
| 咨询部 | 9.00 |
| 教学部 | 9.80 |
| 教职部 | 10.50 |
+-----------+------------+
3.完成上述题目的需求(查出每个部门中薪资最高的员工的姓名,部门,工资)
select name,dep_name,salary from emp join t1 on emp.dep=t1.dep_name and
emp.salary=t1.max_salary;
mysql> select name,dep_name,salary from emp join t1 on emp.dep=t1.dep_name and
emp.salary=t1.max_salary;
+------+-----------+--------+
| name | dep_name | salary |
+------+-----------+--------+
| aaa | 教职部 | 10.5 |
| lll | 咨询部 | 9 |
+------+-----------+--------+
4.更新操作:给(update更新的表不能 与 子查询select的表同表)
1.给每个部门最大薪资+1
update t1 set max_salary=max_salary+1;
mysql> select * from t1;
+-----------+------------+
| dep_name | max_salary |
+-----------+------------+
| 咨询部 | 10.00 |
| 教学部 | 10.80 |
| 教职部 | 11.50 |
+-----------+------------+
2.给t1额外增加一个新部门
insert into t1 values ('打杂部', 100);
mysql> select * from t1; );
+-----------+------------+
| dep_name | max_salary |
+-----------+------------+
| 咨询部 | 10.00 |
| 教学部 | 10.80 |
| 教职部 | 11.50 |
| 打杂部 | 100.00 |
+-----------+------------+
3.修改t1表中的最大工资+1,条件是他的部门必须存在于emp表中的dep_anme中(修改的条件是一个子查询)
update t1 set max_salary=max_salary+1 where dep_name in (select distinct dep from
emp);
mysql> select * from t1;
+-----------+------------+
| dep_name | max_salary |
+-----------+------------+
| 咨询部 | 11.00 |
| 教学部 | 11.80 |
| 教职部 | 12.50 |
| 打杂部 | 100.00 |
+-----------+------------+
4.错误:update更新的表 与 子查询select的表 相同
update t1 set max_salary=max_salary+1 where dep_name in (select distinct dep_name
from t1);
5.删除操作:删除t1表中部门在emp中也有的部门
delete from t1 where dep_name in (select distinct dep from emp);
# 错误: delete删除的表 与 子查询select的表 相同
delete from t1 where dep_name in (select distinct dep_name from t1);