当前位置:网站首页>MySQL---子查询
MySQL---子查询
2022-07-31 17:00:00 【独角鲸需要水】
引入
谁的工资比Abel的高?
方式1:
SELECT salary
FROM employees
WHERE last_name = 'Abel';
SELECT last_name,salary
FROM employees
WHERE salary > 11000;
方式2:自连接
SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e2.`salary` > e1.`salary` #多表的连接条件
AND e1.last_name = 'Abel';
方式3:子查询
SELECT last_name,salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
子查询的基本使用
称谓的规范:外查询(或主查询)、内查询(或子查询)
- 子查询(内查询)在主查询之前一次执行完成。
- 子查询的结果被主查询(外查询)使用 。
- 注意事项
- 子查询要包含在括号内
- 将子查询放在比较条件的右侧
- 单行操作符对应单行子查询,多行操作符对应多行子查询
子查询的分类
角度1:从内查询返回的结果的条目数
单行子查询 vs 多行子查询
角度2:内查询是否被执行多次
相关子查询 vs 不相关子查询
比如:相关子查询的需求:查询工资大于本部门平均工资的员工信息。
不相关子查询的需求:查询工资大于本公司平均工资的员工信息。
单行子查询
查询工资大于149号员工工资的员工的信息
SELECT employee_id,last_name,salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE employee_id = 149
);
返回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
);
返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees
);
查询与141号员工的manager_id和department_id相同的其他员工的employee_id,manager_id,department_id。
方式1:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id = (
SELECT manager_id
FROM employees
WHERE employee_id = 141
)
AND department_id = (
SELECT department_id
FROM employees
WHERE employee_id = 141
)
AND employee_id <> 141;
方式2:了解
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id) = (
SELECT manager_id,department_id
FROM employees
WHERE employee_id = 141
)
AND employee_id <> 141;
查询最低工资大于110号部门最低工资的部门id和其最低工资
SELECT department_id,MIN(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
HAVING MIN(salary) > (
SELECT MIN(salary)
FROM employees
WHERE department_id = 110
);
显式员工的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;
子查询中的空值问题
SELECT last_name, job_id
FROM employees
WHERE job_id =
(SELECT job_id
FROM employees
WHERE last_name = 'Haas');
非法使用子查询
错误:Subquery returns more than 1 row
SELECT employee_id, last_name
FROM employees
WHERE salary =
(SELECT MIN(salary)
FROM employees
GROUP BY department_id);
多行子查询
IN:
SELECT employee_id, last_name
FROM employees
WHERE salary IN
(SELECT MIN(salary)
FROM employees
GROUP BY department_id);
返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE job_id <> 'IT_PROG'
AND salary < ANY (
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
返回其它job_id中比job_id为‘IT_PROG’部门所有工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE job_id <> 'IT_PROG'
AND salary < ALL (
SELECT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
查询平均工资最低的部门id,MySQL中聚合函数是不能嵌套使用的。
方式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
) t_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
)
空值问题
SELECT last_name
FROM employees
WHERE employee_id NOT IN (
SELECT manager_id
FROM employees
);
相关子查询
回顾:查询员工中工资大于公司平均工资的员工的last_name,salary和其department_id
SELECT last_name,salary,department_id
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
方式1:使用相关子查询
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE department_id = e1.`department_id`
);
方式2:在FROM中声明子查询
SELECT e.last_name,e.salary,e.department_id
FROM employees e,(
SELECT department_id,AVG(salary) avg_sal
FROM employees
GROUP BY department_id) t_dept_avg_sal
WHERE e.department_id = t_dept_avg_sal.department_id
AND e.salary > t_dept_avg_sal.avg_sal
查询员工的id,salary,按照department_name 排序
SELECT employee_id,salary
FROM employees e
ORDER BY (
SELECT department_name
FROM departments d
WHERE e.`department_id` = d.`department_id`
) ASC;
结论:在SELECT中,除了GROUP BY 和 LIMIT之外,其他位置都可以声明子查询!
SELECT ....,....,....(存在聚合函数)
FROM ... (LEFT / RIGHT)JOIN ....ON 多表的连接条件
(LEFT / RIGHT)JOIN ... ON ....
WHERE 不包含聚合函数的过滤条件
GROUP BY ...,....
HAVING 包含聚合函数的过滤条件
ORDER BY ....,...(ASC / DESC )
LIMIT ...,....
若employees表中employee_id与job_history表中employee_id相同的数目不小于2,
输出这些相同id的员工的employee_id,last_name和其job_id
SELECT *
FROM job_history;
SELECT employee_id,last_name,job_id
FROM employees e
WHERE 2 <= (
SELECT COUNT(*)
FROM job_history j
WHERE e.`employee_id` = j.`employee_id`
)
EXISTS 与 NOT EXISTS关键字
查询公司管理者的employee_id,last_name,job_id,department_id信息
方式1:自连接
SELECT DISTINCT mgr.employee_id,mgr.last_name,mgr.job_id,mgr.department_id
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.employee_id;
方式2:子查询
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN (
SELECT DISTINCT manager_id
FROM employees
);
方式3:使用EXISTS
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS (
SELECT *
FROM employees e2
WHERE e1.`employee_id` = e2.`manager_id`
);
查询departments表中,不存在于employees表中的部门的department_id和department_name
方式1:
SELECT d.department_id,d.department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;
方式2:
SELECT department_id,department_name
FROM departments d
WHERE NOT EXISTS (
SELECT *
FROM employees e
WHERE d.`department_id` = e.`department_id`
);
SELECT COUNT(*)
FROM departments;
相关更新
相关删除
思考题
边栏推荐
- After the form is submitted, the page does not jump [easy to understand]
- Masterless replication system (1) - write DB when node fails
- 牛客网刷题(四)
- Flex布局详解
- Kotlin协程:续体、续体拦截器、调度器
- 基于C语言的编译器设计与实现
- 联邦学习:联邦场景下的多源知识图谱嵌入
- Golang——从入门到放弃
- Design and Implementation of Compiler Based on C Language
- Huawei's top engineers lasted nine years "anecdotal stories network protocol" PDF document summary, is too strong
猜你喜欢
Smart Trash Can (8) - Infrared Tube Sensor (Raspberry Pi pico)
A common method and the use of selenium
After Effects 教程,如何在 After Effects 中调整过度曝光的快照?
How to switch remote server in gerrit
Design and Implementation of Compiler Based on C Language
这位985教授火了!当了10年博导,竟无一博士毕业!
go mode tidy出现报错go warning “all“ matched no packages
动态规划之线性dp(上)
Implementing distributed locks based on Redis (SETNX), case: Solving oversold orders under high concurrency
Combinatorics Notes (6) Associative Algebra of Locally Finite Partially Ordered Sets, Möbius Inversion Formula
随机推荐
adb shell 报错error: device unauthorized
BOW/DOM(上)
如何识别假爬虫?
牛客网刷题(四)
2020 WeChat applet decompilation tutorial (can applet decompile source code be used)
华为手机一键开启“维修模式”隐藏所有数据,让手机隐私更加安全
牛客 HJ19 简单错误记录
The new telecom "routine", my dad was tricked!
This 985 professor is on fire!After 10 years of Ph.D. supervisor, no one has graduated with a Ph.D.!
利用PHP开发具有注册、登陆、文件上传、发布动态功能的网站
Anaconda如何顺利安装CV2
Go basic part study notes
研发过程中的文档管理与工具
How Redis handles concurrent access
A common method and the use of selenium
How to install CV2 smoothly in Anaconda
【luogu P8326】Fliper (Graph Theory) (Construction) (Eulerian Circuit)
最新神作!阿里巴巴刚出炉的面试参考指南(泰山版),我直接狂刷29天
Multi-datacenter operation and detection of concurrent writes
【pytorch】1.7 pytorch与numpy,tensor与array的转换