MySQL复合查询

目录

1.基本查询回顾

2.多表查询

​编辑

3.自连接

4.子查询

[4.1 单行子查询](#4.1 单行子查询)

[4.2 多行子查询](#4.2 多行子查询)

[4.3 多列子查询](#4.3 多列子查询)

[4.4 在from子句中使用子查询](#4.4 在from子句中使用子查询)

[4.5 合并查询](#4.5 合并查询)


在阅读本章之前,推荐先观看MySQL表的增删改查

前置工作:

创建一个雇员信息表(来自 oracle 9i 的经典测试表)
EMP 员工表
DEPT 部门表
SALGRADE 工资等级表

emp表:

dept表:

SALGRADE工资等级表:

1.基本查询回顾

对于基本查询的相关内容,这里在MySQL表的增删改查已经叙述过,这里就回顾一遍

eg1:查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的****J

cpp 复制代码
mysql> select * from emp where (sal>500 or job='MANAGER') and ename like 'J%';
+-------+-------+---------+------+---------------------+---------+------+--------+
| empno | ename | job     | mgr  | hiredate            | sal     | comm | deptno |
+-------+-------+---------+------+---------------------+---------+------+--------+
|  7566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
|  7900 | JAMES | CLERK   | 7698 | 1981-12-03 00:00:00 |  950.00 | NULL |     30 |
+-------+-------+---------+------+---------------------+---------+------+--------+

eg2:按照部门号升序而雇员的工资降序排序

cpp 复制代码
mysql> select * from emp order by deptno, sal desc;

eg3:使用年薪进行降序排序

cpp 复制代码
mysql> select ename, sal*12+ifnull(comm,0) as '年薪' from emp order by 年薪 desc;

eg4:显示工资最高的员工的名字和工作岗位

cpp 复制代码
mysql> select ename, job from emp where sal = (select max(sal) from emp);
+-------+-----------+
| ename | job       |
+-------+-----------+
| KING  | PRESIDENT |
+-------+-----------+

像这种select内嵌select就是子查询

eg5:显示工资高于平均工资的员工信息

cpp 复制代码
mysql> select ename ,sal from emp where sal=(select avg(sal) from emp);

eg6:显示每个部门的平均工资和最高工资

cpp 复制代码
mysql> select deptno,format(avg(sal),2),max(sal) from emp group by deptno;

eg7:显示平均工资低于2000的部门号和它的平均工资

cpp 复制代码
mysql> select deptno,avg(sal) as avg_sal from emp group by deptno having avg_sal<2000;

eg8:显示每种岗位的雇员总数,平均工资

cpp 复制代码
mysql> select job,count(*), format(avg(sal),2) from emp group by job;

2.多表查询

用一个简单的公司管理系统,有三张表EMP,DEPT,SALGRADE 来演示如何进行多表查询。
显示雇员名、雇员工资以及所在部门的名字因为上面的数据来自 EMP DEPT 表,因此要联合查询

eg1:显示部门号为10的部门名,员工名和工资

cpp 复制代码
mysql> select dname,ename,sal from emp,dept where emp.deptno=dept.deptno and dept.deptno=10;

eg2:显示各个员工的姓名,工资,及工资级别

cpp 复制代码
mysql> select ename, sal, grade from emp, salgrade where emp.sal between losal and hisal;

3.自连接

自连接是指在同一张表连接查询
eg1: 显示员工 FORD 的上级领导的编号和姓名( mgr 是员工领导的编号 --empno )

cpp 复制代码
select empno,ename from emp where emp.empno=(select mgr from emp where
ename='FORD');

eg2: 使用多表查询(自查询)

cpp 复制代码
-- 使用到表的别名
--from emp leader, emp worker,给自己的表起别名,因为要先做笛卡尔积,所以别名可以先识
别
select leader.empno,leader.ename from emp leader, emp worker where
leader.empno = worker.mgr and worker.ename='FORD';

4.子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

4.1 单行子查询

eg:显示SMITH同一部门的员工

cpp 复制代码
mysql> select * from emp WHERE deptno = (select deptno from emp where ename='smith');

4.2 多行子查询

返回多行记录的子查询
eg1:查询和 10 号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含 10 自
己的

cpp 复制代码
select ename,job,sal,deptno from emp where job in (select distinct job from
emp where deptno=10) and deptno<>10;

in关键字:表示这个字段是否在这个集合当中
eg2:显示工资比部门 30 的所有员工的工资高的员工的姓名、工资和部门号

cpp 复制代码
select ename, sal, deptno from EMP where sal > all(select sal from EMP where
deptno=30);

all关键字:表示集合内的所有人
eg3: 显示工资比部门 30 的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门
的员工)

cpp 复制代码
select ename, sal, deptno from EMP where sal > any(select sal from EMP where
deptno=30);

any关键字:表示集合内任意人

4.3 多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句

eg:查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

cpp 复制代码
mysql> select ename from EMP where (deptno, job)=(select deptno, job from EMP
where ename='SMITH') and ename <> 'SMITH';

4.4 在from子句中使用子查询

子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

eg1:显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资

cpp 复制代码
//获取各个部门的平均工资,将其看作临时表
select ename, deptno, sal, format(asal,2) from EMP,
(select avg(sal) asal, deptno dt from EMP group by deptno) tmp
where EMP.sal > tmp.asal and EMP.deptno=tmp.dt;

eg2:查找每个部门工资最高的人的姓名、工资、部门、最高工资

cpp 复制代码
select EMP.ename, EMP.sal, EMP.deptno, ms from EMP,
(select max(sal) ms, deptno from EMP group by deptno) tmp
where EMP.deptno=tmp.deptno and EMP.sal=tmp.ms;
select DEPT.dname, DEPT.deptno, DEPT.loc,cou

eg3:显示每个部门的信息(部门名,编号,地址)和人员数量

1.使用多表

cpp 复制代码
select DEPT.dname, DEPT.deptno, DEPT.loc,count(*) '部门人数' from EMP,DEPT
where EMP.deptno=DEPT.deptno
group by DEPT.deptno,DEPT.dname,DEPT.loc

2.使用子查询

cpp 复制代码
-- 1. 对EMP表进行人员统计
select count(*), deptno from EMP group by deptno;
-- 2. 将上面的表看作临时表
select DEPT.deptno, dname, mycnt, loc from DEPT,
(select count(*) mycnt, deptno from EMP group by deptno) tmp
where DEPT.deptno=tmp.deptno;

4.5 合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all

4.5.1 union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

eg:将工资大于2500或职位是MANAGER的人找出来

cpp 复制代码
mysql> select ename, sal, job from emp where sal>2500 union
    -> select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+

4.5.2 union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行

eg:将工资大于25000或职位是MANAGER的人找出来

cpp 复制代码
mysql> select ename, sal, job from emp where sal>2500 union all
    -> select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+
相关推荐
被AI抢饭碗的人2 小时前
MYSQL基础(二)
数据库·mysql
优秀的老黄2 小时前
MySQL配置从库
linux·数据库·mysql
修行者Java2 小时前
(六)从“缓存混乱难管控”到“Redis高效赋能”——Redis实战进阶指南
数据库·redis·缓存
onebyte8bits2 小时前
NestJS 系列教程(十五):缓存体系设计 —— Redis、接口缓存与缓存三大问题解决方案
数据库·redis·后端·缓存·nestjs
難釋懷2 小时前
Redis主从-repl_backlog原理
数据库·redis·缓存
随便写个昵称2 小时前
Django中的httpresponse返回类型
数据库·django·sqlite
银河麒麟操作系统2 小时前
服务器通用(全架构)【深入解析文件操作中的常见问题:空洞、传输与大小差异】技术文章
运维·服务器·数据库
爬山算法2 小时前
MongoDB(32)如何查看集合中的索引?
数据库·mongodb
艾莉丝努力练剑2 小时前
【MYSQL】MYSQL学习的一大重点:MYSQL库的操作
android·linux·运维·数据库·人工智能·学习·mysql