初识MYSQL —— 复合查询

前言

这里简单回顾一下基本查询的内容:(whereorder bygroup by等等)

练习

这里依旧使用empdeptnosalgrade三张表来做练习

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

根据要求可以分析出来筛选条件:

  • 工资高于500或者岗位是MANAGER;sal>500 or job='MANAGER'
  • 姓名的首字母为大写的Jname like 'J%'

这两个筛选条件要同时满足。

sql 复制代码
select * from emp where (sal>500 or job='MANAGER') and ename like 'J%';

2. 按照部门号升序而雇员的工资降序排序

根据要求,按照部门号升序、雇员工资降序排序。

sql 复制代码
select * from emp order by deptno asc, sal desc;

3. 按照年薪进行降序排序

按照年薪进行降序排序;

年薪 = 月薪*12 + 奖金(根据实际情况来定)

emp表中,comm列是存在NULL的,这里就要进行判断;

使用ifnull函数,如果为NULL就返回0

这里order by执行顺序在select之后,可以使用别名。

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

4. 显示工资最高的员工的名字和工作岗位

根据需求,我们应该要想到一个问题:工资最高的员工可能有很多人;(不能使用order by根据薪资排序,然后取第一行)

这里可以先查询最高工资是多少,然后再使用where进行筛选。

这里使用子查询最好;

简单来说就是一次查询的结果作为条件、表结构。

sql 复制代码
select ename,job from emp where sal=(select max(sal) from emp);

5. 显示工资高于平均工资的员工信息

根据需求,我们可以先查询平均工资,让再查询使用where筛选工资大于平均工资的员工。

使用子查询

sql 复制代码
select * from emp where sal>(select avg(sal) from emp);

6. 显示每个部门的平均工资和最高工资

首先根据部门编号进行分组,然后使用聚合函数maxavg求最高工资和平均工资。

sql 复制代码
select deptno,avg(sal),max(sal) from emp group by deptno;

7. 显示平均工资低于2000的部门号和它的平均工资

先根据部门编号进行分组,然后使用avg求出平均工资,最后再使用having对结果进行筛选。

sql 复制代码
select deptno,avg(sal) as 平均工资 from emp group by deptno having 平均工资<2000;

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

按照部门编号进行分组,然后使用count统计人数,avg求平均工资

sql 复制代码
select deptno,count(*) as 人数, avg(sal) as 平均工资 from emp group by deptno;

一、多表查询

在实际的应用场景中,数据往往来自不同的表,就注定需要多表查询。

例如:查询员工名、员工薪资以及所在部门的名字

其中员工名、员工薪资在表emp中,而部门名在表dept,这里就要联合查询

多表查询select * from emp, dept;是将两种表中数据做笛卡尔积(第一张表中的每一条数据和第二张表中的每一条数据进行组合)

笛卡尔积中有很多数据在这里是不合理的,例如20部门的SMITH,和1030部门信息进行组合。

这里我们只需要emp.deptno = dept.deptno的数据,就可以对两张表笛卡尔积的结果(新表)进行条件筛选。

sql 复制代码
select emp.ename,emp.sal,dept.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno;

1. 查询部门号为10的部门名,员工名和工资

首先要查询的数据来自表empdept,做笛卡尔积然后筛选合理的数据;

然后,对形成的新表做条件筛选,筛选出部门号deptno=10的数据。

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

2. 查询各个员工的姓名,工资,及工资级别

要查询的数据来自表emp和表salgrade

这里要获取工资级别,筛选合理数据的条件为:sal>losal and sal<hisal

sql 复制代码
select ename,sal,grade from emp,salgrade where sal>losal and sal<hisal;

二、自连接

上述操作,要查询数据来自两张不同的表,两张不同的表做笛卡尔积。

而自连接,简单来说就是一张表自己和自己做笛卡尔积。

例如:显示员工FORD的上级领导的编号和姓名

要查询的数据都在表emp中,这里就需要emp表自己和自己做笛卡尔积;(需要给表取别名

sql 复制代码
select emp1.ename,emp2.empno,emp2.ename from emp as emp1, emp as emp2 where emp1.mgr=emp2.empno and emp1.ename='FORD';

当然这里也可以使用子查询,先查询员工FROD的上级领导的员工号;再根据查询到的员工号查询姓名和员工号。

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

三、子查询

子查询是指嵌套在其他sql语句中的select语句。

简单来说就是将select查询的结果当中条件、新表等等再次使用。

1. 单行子查询

例如:查询和SMITH同一部门的员工;

首先要查询SMITH的部门编号,再将查询到的结果当做筛选条件,查询部门为该结果的员工。

sql 复制代码
select * from emp where deptno=(select deptno from emp where ename='SMITH');

2. 多行子查询

上面子查询返回的是一条记录,在作为筛选条件时可以使用=

如果自查询返回的是多条记录,就要使用allinany等关键字来进行判断了。

1. in关键字

查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的

10号部门中,存在多种岗位,使用子查询返回的就是多行数据;

这里要求和10部门的工作岗位相同,即和其中工作岗位一个相同即可。

in(数值1, 数值2, 数值3):判断是否是其中的一个。

不包含10部门自己的员工,最后判断部门编号是否不等于10即可。

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

2. all关键字

all (数值1,数值2,数值3),前面跟>就表示大于所有数值才为true、跟<就表示小于所有数值才为true

查询工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

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

3. any关键字

any(数值1,数值2,数值3),前面跟>就表示大于其中一个数值就为true、跟<就表示小于其中一个数值就为true

查询工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)`

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

3. 多列子查询

单行自查询是指子查询只返回单列、单行数据;多行子查询是指返回单列多行数据;都是针对单列的。

多列子查询是指查询返回多列数据的子查询语句。

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

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

四、内外连接

表的连接分为内连接和外连接;

1. 内连接

内连接实际上就是利用where子句,对两种表的笛卡儿积进行筛选,上述的多表查询其实就是内连接。

sql 复制代码
select 字段 from db1 inner join db2 on 连接条件 and 其它条件;

案例:查询SMITH的名字和部门名称

这里可以按照上述多表查询的写法,两张表使用,隔开;也可以使用内连接,两张表使用inner join隔开。

sql 复制代码
select ename,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';
select ename,dname from emp inner join dept where emp.deptno=dept.deptno and ename='SMITH';

ITH的名字和部门名称

这里可以按照上述多表查询的写法,两张表使用,隔开;也可以使用内连接,两张表使用inner join隔开。

sql 复制代码
select ename,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';
select ename,dname from emp inner join dept where emp.deptno=dept.deptno and ename='SMITH';


本篇文章到这里就结束了,感谢支持

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

相关推荐
撩得Android一次心动2 小时前
Android 四大组件——BroadcastReceiver(广播)
android·java·android 四大组件
ii_best2 小时前
安卓/IOS工具开发基础教程:按键精灵一个简单的文字识别游戏验证
android·开发语言·游戏·ios·编辑器
NPE~3 小时前
[手写系列]Go手写db — — 第七版(实现Disk存储引擎、Docker化支持)
数据库·后端·docker·golang·教程·手写数据库
workflower3 小时前
FDD与其他方法的相似和区别
数据库·算法·需求分析·个人开发
WeiQ_6 小时前
解决phpstudy 8.x软件中php8.2.9没有redis扩展的问题
数据库·redis·缓存
DashVector10 小时前
向量检索服务 DashVector产品计费
数据库·数据仓库·人工智能·算法·向量检索
KYGALYX11 小时前
在Linux中备份msyql数据库和表的详细操作
linux·运维·数据库
檀越剑指大厂11 小时前
金仓KReplay:定义数据库平滑迁移新标准
数据库