概念:出现在其他语句内部的select语句,称为子
查询或内查询
内部嵌套其他select语句的查询,称为外查询或主
查询
分类:
按子查询出现的位置:
select后面
仅仅支持标量查询
from后面
支持表子查询
where或having后面
标量子查询(单行),
列子查询(多行),
行子查询
exists后面(相关子查询)
表子查询
按结果集的行列数不同:
标量子查询(结果只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(一般为多行多列)
一、where或having后面
1、标量子查询(单行子查询)
2、列子查询(多行子查询)
3、行子查询(多列多行、一行多列)
特点:
1.子查询放在小括号内
2.子查询一般放在条件的右侧
3.标量子查询,一般搭配着单行操作符使用
>< >= <= = <>
列子查询,一般搭配着多行操作符使用
IN /NOT IN、ANY/SOME、ALL
4.子查询的执行优先于主查询执行,主查询的条件用到了子查询结果
1.标量子查询
案例一:
谁的工资比 Abel高?
1.先查询Abel的工资
select
salary
from
employees
where
last_name = 'Abel'
select *
from
employees
where
salary>(
select
salary
from
employees
where
last_name = 'Abel'
)
执行单行子查询(标量子查询)
题目:
返回job_id与141号员工相同,salary比143号员工多的员工
姓名,job_id 和工资。
1.先找141号员工的job_id
select
job_id
from
employees
where
employee_id=141;
2.然后找143号的员工的salary
select
salary
from
employees
where
employee_id=143
3.然后找job_id=1,salary>2的员工的姓名,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.多行子查询(列子查询)
返回多行比较操作符
IN /NOT IN、ANY/SOME、ALL
案例:
返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id 以及salary
select
last_name,
employee_id,
job_id,
salary
from
employees
where
salary<all(
select distinct
salary
from
employees
where
job_id = 'IT_PROG'
)and
job_id<>'IT_PROG';
行子查询(结果集一行多列或多行多列)
二、放在select后面
三、放在from后面
案例:查询每个部门的平均工资的工资等级
首先查询每个部门的平均工资
select
AVG(salary),
department_id
from
employees
group by
department_id;
然后将上表与job_grades表连接起来
select
sa.*,
grade_level
from
( select
AVG(salary) ag,
department_id
from
employees
group by
department_id
) sa
JOIN
job_grades g
on
sa.ag BETWEEN lowest_sal and highest_sal;
案例练习
子查询练习
一、查询和Zlotkey相同部门的员工姓名和工资
1、查询Zlotkey的部门
select
department_id
from
employees
where
last_name = 'Zlotkey';
单行单列,判断是标量子查询
然后查询姓名和工资
SELECT
last_name,
salary
from
employees
where
department_id=(select
department_id
from
employees
where
last_name = 'Zlotkey');
二、查询各部门工资比本部平均工资高的员工的员工号,姓名和工资
1.首先查询
各个部门的平均工资
SELECT
department_id,
AVG(salary)
from
employees
GROUP BY
department_id
HAVING
department_id is not null;
2连接1结果集和employees表,进行筛选
SELECT
e.employee_id,
last_name,
e.salary
from
employees e
join
(SELECT
department_id,
AVG(salary) sal
from
employees
GROUP BY
department_id
HAVING
department_id is not null) sa
on
e.department_id = sa.department_id
where
e.salary>sal;