第16节--子查询

子查询

含义:嵌套在其他语句内部的select语句为子查询或内查询,外边的语句可以是instr,update,delete,select等,一般select作为外部语句较多。

外面如果为select,则此语句为外查询或主查询。

 

分类

1. 按出现的位置

select 后面(仅支持标量子查询)

from后面(表子查询)

where或having后面,后可跟标量子查询,列子查询,行子查询

exist后面,可跟 相关子查询,标量子查询,列子查询,行子查询,表子查询

2. 按结果集的行列

标量子查询(单行子查询):结果为一行一列

列子查询(多行子查询):结果集为多行一列

行子查询(结果集为多行多列)

表子查询(结果集为多行多列)

 

 

#1.where 或 having后面

1. 标量子查询(单行子查询)

2. 列子查询(多行子查询)

3. 行子查询(多行多列)

特点: ① 子查询放在小括号内

    ② 子查询一般放在条件的右侧

            ③ 标量子查询,一般搭配着单行操作符使用>, <, >=, <= , =, <>

    ④列子查询,,一般搭配着多行操作符使用 in, any, some, all

说明:子查询的执行优先于主查询,主查询的条件用到了子查询的结果。

标量子查询

#where后

案例:1. 返回job_id 与141号员工相同,salary比143号员工多的员工姓名,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. 查询和Zloktkey相同的部门的员工姓名,工资
select last_name,salary from employees where department_id=(select department_id from employees where last_name='Zlotkey');
案例3. 谁的工资比Abel的工资高(标量子查询)

select last_name from employees where salary>(select salary from employees where last_name='Abel');

#having 子句

案例1:查询最低工资大于50号部门最低工资的部门id和其最低工资

步骤:① select min(salary) from employees where department_id=50;
     ②select  min(salary), department_id from employees  group by department_id 
having min(salary)>(select min(salary) from employees where department_id=50);

 

列子查询

操作符              

 操作符 含义 
 in/not in  等于列表中的任意一个
any/some  和子查询返回的某一个值比较 
    all  和子查询返回的所有值比较 



 

 

 

案例1. 返回location_id 是1400或1700的部门中的所有员工姓名 
步骤:①
select department_id from employees where location_id in(1400,1700); ②select last_name from employees where department_id in (select distinct department_id from locations where location_id in(1400,1700));

 

案例2:返回其他部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号,姓名,job_id以及salary

步骤:① select salary from employees where job_id='IT_PROG';
② select employee_id,last_name,job_id,salary from employees where salary < any(select salary from employees where job_id='IT_PROG') and job_id<>'IT_PROG';

 

行子查询(结果集为一行多列或多行多列)

 

案例 :查询员工编号最小且工资最高的员工员工信息

select * from employees where employee
_id=(select min(employee_id) from employees)
and salary=(select max(salary) from employees);

 

select 后面 仅仅支持标量

查询每个部门的员工个数

select d.*, (select count(*) from employees e where e.department_id=d.department_id) 员工个数 from departments d;

 

from后面

将子查询结果同意当一张表,要求必须起别名

案例:查询每个部门的平均工资的工资等级

步骤:①查询每个部门的平均工资 select avg(salary), department_id from employees group by department_id
② select a.*,job_grades from (select avg(salary) avg, department_id from employees group by department_id) a  inner join jobs j on a.avg between lowest_sal and higest_sal;

 

exists 后面(相关子查询)

语法:exist(完整的查询语句)

结果:1或0(查询结果存在,结果就为1,不存在结果就为0)

 

案例1:查询有员工的部门名

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);

案例2:查询没有女朋友的男神信息 #in

#in
select  bo.*  from  boys bo where bo.id not in(select boyfriend_id from beauty) ;

#exist
  select bo.* from boys bo where not exists(select boyfriend_id from beauty b where bo.id=b.boyfriend_id)
 
posted @ 2020-04-08 17:06  白云~  阅读(127)  评论(0编辑  收藏  举报