前言
上一篇博客,我简单的讲述了联合查询。今天本篇博客我将详细的阐述子查询的四个方面如
标量子查询,列子查询,行子查询,表子查询。
正文
子查询的认识
子查询的认识
子查询:是SQL语句中,嵌套select 语句,称为嵌套查询,又叫子查询。我们可以联系java中的 嵌套循环,模式是差不多的。都是两个循环合在一起。
注意:外部的SQL语句条件是,子查询的结果。
实例
前提
我准备了两张表一张员工信息表员工 employer deptid ,name,和另一张部门表 dept deptid deptName,其中员工表,并没有详细说明员工的部门信息。
问题:查看 销售部的所有员工名字
思路
通过 一张 员工表或部门表都无法解决问题的。在员工表中,我不知道具体部门信息;在部门表中,我不知道具体的员工信息。那该怎么做呢,我们要分两步。
1 通过 部门表。查询到 销售部的部门id
2 从 1 中,我们得到了具体部门id ,作为条件,这样就可以查到,我们想要的员工信息了
按照原有的写法代码如下
1 select deptid from dept where deptName='销售表';
2 从 1 中得到结果假设是 在员工表中deptid =1
select name from employer where deptid=1;
通过以上的分析,我们其实要写两道查询语句,才可以得到结果,这样写是比较繁琐的,因此才有了子查询
代码
select name from employer where deptid=( select deptid from dept where deptName='销售表');-----
这也是我后面要讲的标量子查询
子查询的分类
我们根据子查询的结果分为,以下几种:
标量子查询
列子查询
行子查询
表子查询
标量子查询
注意
1 子查询的外层SQL语句,不一定要具有查询功能,也可以其他的。如 更新 update ,删除 delete 之类的
2 根据子查询位置分为:where 之后,from之后,,select之后
标量子查询
标量子查询的理解
理解:子查询的查询结果是单个值如单个日期,名字等 。
标量子查询的使用
1 查询销售部所有员工名字
背景:我准备了两张表一张员工信息表员工 employer deptid(部门id) ,name(名字),和另一张部门表 dept deptid ,deptName(部门名字)其中员工表,并没有详细说明员工的部门信息。
思路
a 先得到部门表中销售部的部门id
代码如下
select deptid from dept where deptName='销售表';
b 得到具体的部门id,就可以在员工表的到目标员工名字
代码如下
select name from employer where deptid=( select deptid from dept where deptName='销售表');
2 查询 比员工 名字叫 方东 之后入职的员工名字
背景:我准备一张员工信息表员工 employer time,name
思路
a 得到员工方东 的入职时间
代码如下
select time from employer where name='方东';
b 根据方东的入职时间,推算在方东之后入职的员工的名字
代码如下
select name from employer where time>(select time from employer where name='方东');
列子查询
列子查询的理解
理解:子查询,查询的结果只有一列(可以是多行)
列子查询的使用
常见的操作符有: in ,not in , any ,some,all
1 查询销售部和市场部的所有员工信息
背景:部门表 dept deptid ,deptName,员工表 employer deptid 其中员工表,并没有详细说明员工的部门信息。
思路
a 知道销售部 和市场部的部门id
代码如下
select deptid from dept where deptName ='销售表‘ or deptName ='市场部’;
b 根据他们的部门id ,从员工表中,获取员工信息
最终代码如下
select * from employer where deptid in ( select deptid from dept where deptName ='销售表‘ or deptName ='市场部’) ;
注意: 操作符 in,指定范围内,多选一
2 查询比财务部所有人工资高的员工信息
背景: 部门表 dept deptid (部门id) ,deptName(部门名字),员工表 employer deptid ,salary(薪资) 其中员工表,并没有详细说明员工的部门信息。
思路
a 查询财务部 的员工工资
代码如下
select salary from employer where deptid =(select deptid from dept where deptName ='财务部');
b 从 a 中得到结果,作为b 的条件,找到比所有人工资高的员工信息
最终代码如下
select * from employer where salary >all (select salary from employer where deptid =(select deptid from dept where deptName ='财务部'));
注意:题中要求,比所有人的员工工资都高的员工信息,使用操作符 all
3 查询比研发部其中任意人工资高的员工信息
背景: 部门表 dept deptid ,deptName(部门名字),员工表 employer deptid(部门id) ,salary(薪资) 其中员工表,并没有详细说明员工的部门信息。
思路
a 查询研发部的员工工资
代码如下
select salary from employer where deptid =(select deptid from dept where deptName ='研发部');
b 从a 中得到,研发部的员工工资后,找到比任意一个都高的员工信息,就是我们要的答案。
最终代码如下
select * from employer where salary >any (select salary from employer where deptid =(select deptid from dept where deptName ='研发部'));
注意: 操作符 any 是满足任意一个条件
行子查询
行子查询的理解
行子查询:子查询返回的结果为一行---一行多列。
行子查询的使用
注意:行子查询常见的操作符:= <> in not in
1 查询 与' 张无忌'的薪资 和直属领导相同的员工信息
背景:部门表 dept deptid (部门id) ,deptName(部门名字),员工表 employer deptid ,salary(薪资) ,mannger(直属领导) 其中员工表,并没有详细说明员工的部门信息。
思路
a 查询 张无忌的薪资 和直属领导
代码如下
select salary manager from employer where name ='张无忌’;
b查询 与' 张无忌'的薪资 和直属领导相同的员工信息
代码如下
select * from employer where (salary,manager )=(select salary manager from employer where name ='张无忌’);
注意:由于我们子查询的结果是 薪资 和 直属领导 ,所以在外层SQL 语句中,我们应该把salary,manager 组合起来写,并加上括号。
表子查询
表子查询的理解
表子查询:子查询返回的结果为一张表。
表子查询的使用
1 查询鹿杖客 和宋远桥的职位和薪资相同的员工信息
背景:部门表 dept deptid ,deptName,员工表 employer deptid ,salary ,job(职位)其中员工表,并没有详细说明员工的部门信息。
思路
a 查询 鹿杖客 和宋远桥的职位和薪资
代码如下
select job ,salary from employer where name=‘鹿杖客' or name ='宋远桥';
b查询鹿杖客 和宋远桥的职位和薪资相同的员工信息
代码如下
select * from employer where (job,salary ) in (select job ,salary from employer where name=‘鹿杖客' or name ='宋远桥');
2 查询入职日期 是‘2006-01-01’之后的员工信息及其部门信息
背景:部门表 dept deptid ,deptName,员工表 employer deptid ,salary ,time(入职日期)其中员工表,并没有详细说明员工的部门信息。
思路
a 查询入职日期 是‘2006-01-01’之后的员工信息
代码如下
select * from employer where time > ‘2006-01-01’;
b 根据查到的员工信息,查询到对应的部门信息
代码如下
select e. * d.* from (select * from employer where time > ‘2006-01-01’) e left join dept d on e.deptid=d.deptid ;