前言
这里简单回顾一下基本查询的内容:(where、order by、group by等等)
练习:
这里依旧使用emp、deptno和salgrade三张表来做练习
1. 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J
根据要求可以分析出来筛选条件:
- 工资高于500或者岗位是MANAGER;
sal>500 or job='MANAGER' - 姓名的首字母为大写的
J;name 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. 显示每个部门的平均工资和最高工资
首先根据部门编号进行分组,然后使用聚合函数max和avg求最高工资和平均工资。
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,和10、30部门信息进行组合。
这里我们只需要emp.deptno = dept.deptno的数据,就可以对两张表笛卡尔积的结果(新表)进行条件筛选。
sql
select emp.ename,emp.sal,dept.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno;
1. 查询部门号为10的部门名,员工名和工资
首先要查询的数据来自表emp和dept,做笛卡尔积然后筛选合理的数据;
然后,对形成的新表做条件筛选,筛选出部门号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. 多行子查询
上面子查询返回的是一条记录,在作为筛选条件时可以使用=;
如果自查询返回的是多条记录,就要使用all、in、any等关键字来进行判断了。
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