MySQL数据库操作(五)——多表查询

个人博客:haichenyi.com。感谢关注

合并结果集 union all(包含相同行)、union(去除相同行)

  把查询的结果合并到一起。要求: 查询的结果列数相同,列类型相同

create table emp(
    eid int,
    ename varchar(50),
    eage int
);

create table stu(
    sid int,
    sname varchar(50)
);

//合并结果集(加上all,包含相同的行)
select eid,ename from emp
union all
select * from stu;

//合并结果集(去掉all,去除相同行)
select eid,ename from emp
union
select * from stu;

连接查询

内连接

方言: select * from 表1,表2 where 条件

表a有三条数据:q,w,e
表b有两条数据:h,j
select * from a,b;
得出的结果是表a与表b的笛卡尔集,也就是会得到6条数据,
分别:qh,qj,wh,wj,eh,ej
去除无用的笛卡尔集,加上where后面的条件
连表查询会有附表的外键=主表的主键这个条件

select * from student,teacher where student.tid=teacher.tid;

查询学生的全部信息,需要查询学生表和老师表,
条件是学生表里面的老师id等于老师表里面的老师id,
这样查出来的结果就是我们想要的结果
例子:要求打印员工姓名,工资以及部分名称
     员工姓名,工资在emp表,部门名称在dept表
select emp.ename,emp.sal,dept.dname
from emp,dept
where emp.did=dept.did;

如果嫌弃表名字太长了可以这样:
select e.ename,e.sal,d.dname
from emp e,dept d
where e.did=d.did;

标准: select * from 表1 别名1 inner join 表2 别名2 on 条件

别名都是可选的,条件跟上面写的一样。两者的区别就只有二个:
1、方言连接两个表是用逗号,标准连接两个表是用 inner join
2、条件:方言用where,标准用on

select e.ename,e.sal,d.dname
from emp e inner join dept d
where e.did=d.did;
外连接 一主一次

左外连接 left outer join ,左表为主表,右表为次表,左表中不论满足不满足条件都查询出来,右表中对应的位置用null补位

查询所有员工名称,工资以及部门名称,部门名称为null的填无部分
select e.ename as 姓名,e.sal as 工资,d.ifnull(dname,'无部门') as 部门名称
from emp e left outer join dept d
where e.did=d.did;

右外连接 right outer join 与左外对应

子查询 一条sql语句中有多个select关键字,ALL,ANY,IN

//查询员工中最高工资员工的详细信息
select * from emp where sal=MAX(sal);
//上面这个写法是错误的,条件中是不能出现集合函数
//上面这个写法是错误的,条件中是不能出现集合函数
//上面这个写法是错误的,条件中是不能出现集合函数


//1、先查最高工资
select MAX(sal) from emp;
//2、最高工资的员工信息
select * from emp where sal=(select MAX(sal) from emp);
//上面这个写法才是正确的
//上面这个写法才是正确的
//上面这个写法才是正确的

出现的位置: 1、from后作为表 2、where后作为条件

上面那条sql语句就是作为条件
//查询部门等于30的员工的姓名和年龄
select e.name,e.age from (select * from emp where did=30) e;
//上面这条就是from后面作为表

1、打印高于平均工资的所有人的信息(单行单列作为条件)

select * from emp where (sal>select AVG(sal) from emp);

2、打印大于30部门的所有员工工资的员工信息(多行单列作为条件)

select * from emp where sal > ALL (select sal from emp where did=30);

3、打印大于30部门任意一人员工工资的员工信息

select * from emp where sal> ANY (select sal from emp where did = 30);

4、打印工作和部门与张三相同的员工信息

select * from emp where (job,did) IN (select job,did from emp where ename='张三');

练习题

前提条件已知四张表

员工表emp(eid,ename,job,emid,etime,sal,edid)
部门表dept(did,dname,dloc)
薪资等级表salgrade(grade,losal,hisal)
领导表mgr(mid,mname,mtime)

1、查询至少有一个员工的部门,显示部门编号,部门名称,部门位置,部门人数

分析:
1、列:d.did,d.dname,d.dloc,部门人数
2、表:dept d,emp e
条件:e.did=d.did

//查询部门编号,部门名称,部门位置
select * from dept;

//查询部门人数
select e.did,count(*) from emp group by e.did;

//把上面查询的两张表内连接
select * from dept inner join select e.did,count(*) from emp group by e.did;

//加上条件,给出别名
select d.*,z1.cnt from dept d inner join (select did,count(*) cnt from emp group by e.did) z1 where d.did=z1.did;

2、查询所有员工名称及其直接上级领导名称

分析:
1、列:e.ename,m.mname
2、表:emp e,mgr m
条件:e.emid=m.mid
//查询员工名称
select ename from emp;
//查询领导名称
select mname from mgr;

select ename from emp e left outer join (select mname from mgr ) m on e.emid = m.mid; 

3、列出受雇佣日期早于直接上级的所有员工编号,姓名,以及部门名称

分析:
1、列:e.eid,e.ename,d.dname
2、表:emp,mgr,dept
//查询受雇佣日期早于直接上级领导的员工信息
select etime from emp;
select mtime from mgr;

select * from emp e
inner join 
select mtime from mgr m
on e.emid=m.mid and e.etime<m.mtime

//再把部门名称加上
(select eid,ename,edid from emp e
inner join 
select mtime from mgr m
on e.emid=m.mid and e.etime<m.mtime) z1 
left outer join 
select dname from dept d 
on z1.edid = d.did;

或者
select e.eid,e.ename,d.dname
from emp e,mgr m,dept d
where e.emid=m.mid and e.etime<m.mtime and e.edid=d.did;

4、列出部门名称和这些部门的员工信息,同事列出没有员工的部门

分析:
1、列:员工信息,和部门名称,没有员工的部门也要列出来
2、表:emp,dept

select e.*,d.dname from emp e 
right outer join 
dept d
on e.edid=d.did;

5、列出最低薪资大于15000的各种工作以及从事此工作的人数

分析:
1、列:工作类型,人数
2、表:emp
条件:min(sal)>15000

select job,count(*)
from emp
group by job
having min(sal)>15000

6、列出在销售部工作的员工姓名,假定不知道销售部的部门编号

分析:
1、列:员工姓名
2、表:emp,dept
条件:e.edid=d.did

select ename
from emp e
where e.edid=(select did from dept where dname='销售部');

7、列出薪资高于公司平均工资的所有员工信息,所在部门名称,上级领导,工资等级

分析:
1、列:员工信息,部门名称,上级领导名称,工资等级
2、表:emp,dept,mgr
条件:sal>avg(sal),e.edid=d.did,e.emid=m.mid
//先查询高出平均工资的员工信息
select * from emp where sal>(select avg(sal) from emp);

//把后面的表一个一个的加上去
//加部门名称
select e.*,d.dname
from 
    emp e left outer join dept d on e.edid=d.did
where e.sal>(select avg(sal) from emp)

//加上级领导名称
select e.*,d.dname,m.mname
from 
    emp e left outer join dept d on e.edid=d.did
    left outer join mgr m on e.emid = m.mid
where e.sal>(select avg(sal) from emp)

//最后加工资等级
select e.*,d.dname,m.mname,s.grade
from 
    emp e left outer join dept d on e.edid=d.did
    left outer join mgr m on e.emid = m.mid
    left outer join salgrade s on e.sal between s.losal and hisal
where e.sal>(select avg(sal) from emp)

8、列出与张三从事相同工作的所有员工以及部门名称

分析:
1、列:所有员工,部门名称
2、表:emp,dept
条件:张三的工作相同,e.edid=d.did

select e.*,d.dname from emp e 
left outer join dept d
on e.edid=d.did
where e.job=(select job from emp where ename='张三');

或者

select e.*,d.dname from emp e,dept d where e.edid=did and e.job=(select job from emp where ename='张三');

9、列出薪资高于30部门的所有员工薪资的员工的姓名和薪资,部门名称


select e.ename,e.sal,d.dname from emp e left outer join dept d
where e.sal > all (select sal from emp where edid=30) and e.edid = d.did;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海晨忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值