文章目录
- 1、需求分析与问题解决
- 1.1 实际问题
- 1.2 子查询的基本使用
- 1.3 子查询的分类
- 2、单行子查询
- 2.1 单行比较操作符
- 2.2 代码示例
- 2.3 HAVING中的子查询
- 2.4 CASE中的子查询
- 2.5 子查询中的空值问题
- 2.6 非法使用子查询
- 3、多行子查询
- 3.1 多行比较操作符
- 3.2 代码示例
- 3.3 空值问题
- 4、相关子查询
- 4.1 相关子查询执行流程
- 4.2 代码示例
- 4.3 EXISTS 与 NOT EXISTS关键字
- 4.4 相关更新
- 4.5 相关删除
- 5、抛一个思考题
子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入。 SQL 中子查询的使用大大增强了 SELECT查询的能力,因为很多时候查询需要从结果集中获取数据,或者需要从同一个表中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集 合)进行比较。
1、需求分析与问题解决
1.1 实际问题
现有的解决方式:
#方式一:
SELECT salary
FROM employees
WHERE last_name = 'Abel';#11000
SELECT last_name,salary
FROM employees
WHERE salary > 11000;
#方式二:自连接
SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e1.last_name = 'Abel'
AND e1.`salary` < e2.`salary`
#方式三:子查询
#方式三:子查询
SELECT last_name,salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
1.2 子查询的基本使用
1.3 子查询的分类
2、单行子查询
2.1 单行比较操作符
2.2 代码示例
2.3 HAVING中的子查询
- 首先执行子查询
- 想主查询中的HAVING子句返回结果
2.4 CASE中的子查询
在CASE表达式中使用单列子查询:
题目:显式员工的employee_id,last_name和location。其中,若员工department_id与location_id为1800的department_id相同,则location为’Canada’,其余则为’USA’。
SELECT employee_id, last_name,
(CASE department_id
WHEN
(SELECT department_id FROM departments
WHERE location_id = 1800)
THEN 'Canada' ELSE 'USA' END) location
FROM employees;
2.5 子查询中的空值问题
SELECT last_name, job_id
FROM employees
WHERE job_id =
(SELECT job_id
FROM employees
WHERE last_name = 'Haas');
2.6 非法使用子查询
SELECT employee_id, last_name
FROM employees
WHERE salary =(
SELECT MIN(salary)
FROM employees
GROUP BY department_id
);
3、多行子查询
- 也称为集合比较子查询
- 内查询返回多行
- 使用多行比较操作符
3.1 多行比较操作符
3.2 代码示例
题目:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
题目:返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
题目:查询平均工资最低的部门id
#方式1:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) = (
SELECT MIN(avg_sal)
FROM (
SELECT AVG(salary) avg_sal
FROM employees
GROUP BY department_id
) dept_avg_sal
)
#方式2:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL (
SELECT AVG(salary) avg_sal
FROM employees
GROUP BY department_id
)
3.3 空值问题
SELECT last_name
FROM employees
WHERE employee_id NOT IN (
SELECT manager_id
FROM employees
);
4、相关子查询
4.1 相关子查询执行流程
4.2 代码示例
4.3 EXISTS 与 NOT EXISTS关键字