概念:出现在其他语句内部的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的工资

  1. select
  2. salary
  3. from
  4. employees
  5. where
  6. last_name = 'Abel'
  7. select *
  8. from
  9. employees
  10. where
  11. salary>(
  12. select
  13. salary
  14. from
  15. employees
  16. where
  17. last_name = 'Abel'
  18. )

执行单行子查询(标量子查询)
题目:
返回job_id与141号员工相同,salary比143号员工多的员工
姓名,job_id 和工资。
1.先找141号员工的job_id

  1. select
  2. job_id
  3. from
  4. employees
  5. where
  6. employee_id=141;

2.然后找143号的员工的salary

  1. select
  2. salary
  3. from
  4. employees
  5. where
  6. employee_id=143

3.然后找job_id=1,salary>2的员工的姓名,job_id 和工资。

  1. select
  2. last_name,
  3. job_id,
  4. salary
  5. from
  6. employees
  7. where
  8. job_id=(
  9. select
  10. job_id
  11. from
  12. employees
  13. where
  14. employee_id=141
  15. )and
  16. salary>(
  17. select
  18. salary
  19. from
  20. employees
  21. where
  22. employee_id=143
  23. );

2.多行子查询(列子查询)
返回多行比较操作符
IN /NOT IN、ANY/SOME、ALL
案例:
返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id 以及salary

  1. select
  2. last_name,
  3. employee_id,
  4. job_id,
  5. salary
  6. from
  7. employees
  8. where
  9. salary<all(
  10. select distinct
  11. salary
  12. from
  13. employees
  14. where
  15. job_id = 'IT_PROG'
  16. )and
  17. job_id<>'IT_PROG';

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

二、放在select后面

一般为一行一列

三、放在from后面

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

  1. select
  2. AVG(salary),
  3. department_id
  4. from
  5. employees
  6. group by
  7. department_id;

image.png
然后将上表与job_grades表连接起来

  1. select
  2. sa.*,
  3. grade_level
  4. from
  5. ( select
  6. AVG(salary) ag,
  7. department_id
  8. from
  9. employees
  10. group by
  11. department_id
  12. ) sa
  13. JOIN
  14. job_grades g
  15. on
  16. sa.ag BETWEEN lowest_sal and highest_sal;

image.png
EXISTS
返回行,true和false
效果和in差不多

案例练习

子查询练习
一、查询和Zlotkey相同部门的员工姓名和工资
1、查询Zlotkey的部门

  1. select
  2. department_id
  3. from
  4. employees
  5. where
  6. last_name = 'Zlotkey';

image.png
单行单列,判断是标量子查询
然后查询姓名和工资

  1. SELECT
  2. last_name,
  3. salary
  4. from
  5. employees
  6. where
  7. department_id=(select
  8. department_id
  9. from
  10. employees
  11. where
  12. last_name = 'Zlotkey');

image.png
二、查询各部门工资比本部平均工资高的员工的员工号,姓名和工资
1.首先查询
各个部门的平均工资

  1. SELECT
  2. department_id,
  3. AVG(salary)
  4. from
  5. employees
  6. GROUP BY
  7. department_id
  8. HAVING
  9. department_id is not null;

image.png
2连接1结果集和employees表,进行筛选

  1. SELECT
  2. e.employee_id,
  3. last_name,
  4. e.salary
  5. from
  6. employees e
  7. join
  8. (SELECT
  9. department_id,
  10. AVG(salary) sal
  11. from
  12. employees
  13. GROUP BY
  14. department_id
  15. HAVING
  16. department_id is not null) sa
  17. on
  18. e.department_id = sa.department_id
  19. where
  20. e.salary>sal;