Welcome To Jeremy's Blog --------------------------            JeremyYu

9.子查询


1.子查询介绍:

(1).含义:

出现在其他语句中的select语句, 称为子查询或内查询(其他语句包括但不限于SQL的增删改查语句), 内部嵌套其他select语句的查询, 称为外查询或主查询.

返回顶部


 

(2).分类:
 1 1).按子查询的出现位置:
 2   select后面:标量子查询
 3   from后面:支持表子查询
 4   where或having后面:\*****标量子查询(单行子查询)\*****,列子查询(多行子查询),行子查询(行子查询用的较少)
 5   exits后面

6 2).按结果集的行列数不同: 7   标量子查询(结果集只有一行一列) 8   列子查询(结果集只有一列多行) 9   行子查询(结果集有一行多列) 10   表子查询(结果集一般为多行多列)

 

返回顶部


 

(3).特点:
1 (1).子查询放在小括号内
2 (2).子查询一般放在条件的右侧
3 (3).标量子查询,一般搭配着单行操作符使用:>,<,=,>=,<=,<>
4    列子查询,一般搭配多行操作符使用:in, any/some, all
5 (4).子查询的执行优先于主查询,主查询要应用子查询的结果

 

返回顶部


2.出现where和having后面的子查询

(1)标量子查询(单行子查询)
 1 # 案例1: 查询谁的工资比Abel高

2 # 分析: 3     1).查询出Abel的工资 4       select salary 5       from employees 6       where last_name='Abel'; 7     2).查询员工信息,筛选条件为工资大于上面的查询结果(最后整合的查询语句) 8       select* 9       from employees 10       where salary>( 11       select salary 12       from employees 13       where last_name ='Able' 14       );
15 # 案例1最后的查询语句: 16       select* 17       from employees 18       where salary>( 19       select salary 20       from employees 21       where last_name ='Able' 22       );

 

返回顶部

 1 # 案例2: 返回job_id与141号员工相同, salary比143号员工多的员工的姓名, job_id和工资

2 # 分析: 3     1).查询141号员工的job_id 4       select job_id 5       from employees 6       where employee_id=141; 7     2).查询143号员工的工资 8       select salary 9       from employees 10       where employee_id=143; 11     3).查询员工的姓名, job_id,工资,筛选条件为job_id等于1的查询结果,工资大于2的查询结果 12       select last_name, job_id, salary 13       from employees 14       where job_id =( 15       select job_id 16       from employees 17       where employee_id=141 18       )and salary >( 19       select salary 20       from employees 21       where employee_id=143 22       );
23 # 案例2最后的查询语句: 24       select last_name, job_id, salary 25       from employees 26       where job_id =( 27       select job_id 28       from employees 29       where employee_id=141 30       )and salary >( 31       select salary 32       from employees 33       where employee_id=143 34       );

 

返回顶部

 1 # 案例3: 返回工资工资最少的员工的last_name, job_id 和 salary

2 # 分析: 3     1).查询公司的最低工资 4       select min(salary) 5       from employees; 6     2).查询员工的名字, job_id, salary,筛选条件是工资等于上面的查询结果 7       select last_name, job_id, salary 8       from empl0yees 9       where salary =( 10       select min(salary) 11       from employees 12       );
13 # 案例3最后查询语句: 14       select last_name, job_id, salary 15       from empl0yees 16       where salary =( 17       select min(salary) 18       from employees 19       );

 

返回顶部

 1 # 案例4: 查询最低工资大于50号部门最低工资的部门id和其最低工资
 2 # 分析:
 3     1).查询50号部门的最低工资
 4       select min(salary)
 5       from employees
 6       where department_id =50;
 7     2).查询出各部门最低工资
 8       select min(salary), department_id
 9       from employees
10       groupby department_id
11     3)查询部门和该最低工资,筛选条件为其最低工资大于上面的查询结果
12       select min(salary), department_id
13       from employees
14       groupby department_id
15       having (
16       select min(salary)
17       from employees
18       where department_id =50
19       );
20 # 案例4最后查询语句: 21       select min(salary), department_id 22       from employees 23       groupby department_id 24       having ( 25       select min(salary) 26       from employees 27       where department_id =50 28       );

 

(注意: 非法使用标量子查询:子查询结果不是一行一列, 会出现查询错误)

返回顶部


(2)列子查询(多行子查询)
 1 多行子查询:
 2     -返回多行数据
 3     -使用多行比较操作符:in/notin等于列表中的任意一个
 4               any / some 和子查询返回的某一个值比较
 5               all 和子查询返回的所有值比较


6 # 案例1: 返回location_id是1400或1700的部门中的所有员工姓名

7 # 分析: 8     1).查询location_id是1400或1700的部门 9       select department_id 10       from departments as d 11       where d.location_id in(1400,1700); 12     2).查询所有的员工姓名,筛选条件为:员工的部门id在上面的查询结果中 13       select last_name 14       from employees as e 15       where e.department_id in( 16       select department_id 17       from departments as d 18       wherer d.location_id in(1400,1700) 19       );
20 # 案例1的最终查询语句为: 21       select last_name 22       from employees as e 23       where e.department_id in( 24       select department_id 25       from departments as d 26       wherer d.location_id in(1400,1700) 27       );

 

返回顶部

 1 # 案例2: 返回其他工种中比job_id为`IT_PROG`工种任一工资低的员工的员工号, 姓名, job_id以及salary

2 # 分析: 3     1).查询job_id为`IT_PROG`的工种的所有工资 4       select distinct salary 5       from employees 6       where job_id =`IT_PROG`; 7     2).查询其他员工的员工号,名字, job_id, salary,筛选条件为员工的工资低于上面结果的任一值 8       select employee_id, last_name, job_id, salary 9       from employees as e 10       where e.salary < any( 11       select salary 12       from employees 13       where job_id =`IT_PROG` 14       )and job_id<>'IT_PROG';
15 # 案例2的最终查询语句为: 16       select employee_id, last_name, job_id, salary 17       from employees as e 18       where e.salary < any( 19       select salary 20       from employees 21       where job_id =`IT_PROG` 22       )and job_id<>'IT_PROG';

 

返回顶部

1 # 案例3:返回其他部门中比job_id为`IT_PROG`部门所有工资都低的员工的员工号, 姓名, job_id以及salary
2       select last_name, employee_id, job_id, salary
3       from employees
4       where salary < all(
5       select distinct salary
6       from employees
7       where job_id=`IT_PROG`
8       )and job_id <>`IT_PROG`;

 

(3)行子查询(用的较少)
1 # 案例: 查询员工编号最小并且工资最高的员工信息
2       select  *
3       from employees
4       where(employee_id, salary)=(
5       select min(employee_id), max(salary)
6       from employees
7       );

 

返回顶部 


 

3.子查询位于select后面

1 # 案例: 查询每个部门的员工个数
2       select d.*,(
3       select count(*)
4       from employees as e
5       where e.department_id = d.department_id
6       )个数
7       from departments as d;

 

返回顶部


4.子查询位于from后面

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


2 # 分析: 3     1).查询每个部门的平均工资 4         select avg(salary), department_id 5         from employees as e 6         groupby department_id; 7     2)在上面的查询结果的基础上连表查询 8         select ag_dep.*, g.grade_level 9         from( 10           select avg(salary)as ag, department_id # 该表中有两个字段, ag(平均工资), 部门id 11           from employees as e 12           groupby department_id; 13           )as ag_dep 14         inner join job_grades as j 15         on ag_dep.ag between j.lowest_sal and highest_sal;# 连接条件是部门平均工资在工资级别表的相应范围

 

返回顶部


5.子查询放在exists后面(相关子查询)

 1 1.语法:
 2   exists(完整的查询语句)
 3 2.结果:返回布尔值,1或0
 4 3.执行顺序:先执行主查询,再根据子查询来过滤主查询的结果

5 # 案例: 查询有员工的部门的部门名 6       select department_name 7       from departments as d 8       where exists( 9       select* 10       from employees as e 11       where d.department_id = e.department_id 12       );

 

返回顶部

posted on 2018-03-14 22:23  Jeremy_Yu  阅读(64)  评论(0)    收藏  举报

导航