MySql中多表查询(一)

单表查询

ifnull(a,b):如果不为空,为a,如果为空,为b.

例1.查询工资大于500或者岗位为Manager的雇员,同时满足他们姓名为首字母大学J

select ename,sal,mgr from emp
where (sal>500 or job=’MANAGER’) and ename like ‘J%’;
这里写图片描述

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

select ename,deptno,sal from emp
order by deptno ,sal desc;
这里写图片描述

注意:在前面的优先排序,后边的在第一个的基础上进行排序

例3.使用年薪排序

select ename,sal*12+ifnull(comm,0) as ‘年薪’
from EMP order by ‘年薪’ desc;
这里写图片描述

例4.分页查询

select 字段 from 表名 where 条件 limit 起始位置,记录条数

按照雇员的empno升序排序,每页只显示3条记录,显示第一页
select ename,empno from emp
order by empno
limit 0,3;
这里写图片描述

例5.显示工资最高的员工姓名和工作岗位

select ename,job from emp
where sal=(select max(sal) from emp);
属于where条件的子查询
这里写图片描述

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

select ename,job,sal from emp
where sal>(select avg(sal) from emp);
这里写图片描述

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

select deptno,format(avg(sal),2) as ‘平均工资’,max(sal) as ‘最高工资’
from emp
group by deptno;
这里写图片描述

多表查询

笛卡尔积查询

从第一张表中选出第一条记录,和第二个表中的所有记录进行组合;然后从第一张表中取得第二条记录,和第二张表中的所有记录进行组合;依次类推,直到最后一张表。像这样不加过滤条件,得到的结果称为笛卡尔积。

select * from emp,dept;

例1.查询雇员名、工资以及所在的部门名字

select ename,sal,dname
from emp,dept
where emp.deptno=dept.deptno;
这里写图片描述

例2.显示部门标号为10的部门名,员工名和他的工资

select dname,ename,sal
from emp,dept
where emp.deptno=dept.deptno and dept.deptno=10;
如果多个表中有同一属性,一定要写它所在的表的名字。
这里写图片描述

自连接

在同一张表连接查询

例3.显示员工名叫FORD的员工的上级领导的姓名

(1)单表查询
select ename from emp
where empno=(select mgr from emp where ename=’FORD’);
这里写图片描述
(2)多表查询
select leader.ename
from emp worker,emp leader
where worker.mgr=leader.empno
and worker.ename=’FORD’;
将emp表看成两个表,起了别名,一个为worker,一个为leader.
这里写图片描述

子查询

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

1.单行子查询(单行单列)

子查询的结果只有一行

例4.显示和smith同一部门的员工信息

select ename,job,sal
from emp
where (deptno,job) = (select deptno,job from emp where ename=’SMITH’);
这里写图片描述

2.多行子查询(in,all,any)(多行单列)

返回多条记录的子查询

(1)使用关键字in

例5.查询和10号部门工作相同的enam,job,sal,deptno,但是不包含10号部门自己

select ename,job,sal,deptno
from emp
where job in(select job from emp where deptno=10)
and deptno<>10;
这里写图片描述
(2)使用关键字all

例6.显示出工资比部门标号为30的所有员工工资高的姓名、工资和部门号

select ename,sal,deptno
from emp
where sal > all(select sal from emp where deptno=30);
这里写图片描述
或者
select ename,sal,deptno
from emp
where sal > (select max(sal) from emp where deptno =30);
这里写图片描述
(3)使用关键字any

例7.显示出工资比部门为30的任意一个员工工资高的姓名、工资和部门号

select ename,sal,deptno
from emp
where sal > any(select sal from emp where deptno=30);
这里写图片描述

3.多列子查询(查询返回多个列数据的子查询语句)(多行多列)

例8.查询和smith部门和岗位完全相同的所有雇员信息,不包含smith本人

select ename,job,sal
from emp
where (deptno,job)=(select deptno,job from emp where ename=’smith’)
and ename<>’smith’;
这里写图片描述

from子查询(将子查询当做临时表)

例9.显示高于自己工作部门的平均工资的员工信息

select ename,job,sal
from emp,
(select avg(sal) as avg_sal,deptno from emp
group by deptno) as tmp
where emp.deptno = tmp.deptno
and sal > tmp.avg_sal;
将from子查询(自己工作部门的平均工资)作为tmp表。
这里写图片描述

例10.查找每个部门工资最高的人的详细信息

select ename,job,sal
from emp,
(select max(sal) as max_sal,deptno from emp group by deptno)as tmp
where emp.deptno=tmp.deptno
and sal=tmp.max_sal;
这里写图片描述

例11.显示出每个部门信息(部门名,编号,地址)和人员数量

//多表查询
select dname,dept.deptno,loc,count(*)as ‘人员数量’
from emp,dept
where emp.deptno=dept.deptno
group by deptno;
这里写图片描述
//from子查询
select dname,dept.deptno,loc,per_num
from dept,
(select count(*) as per_num,deptno from emp group by deptno) as tmp
where dept.deptno=tmp.deptno;
这里写图片描述
//自我复制
1.create table temp like emp;
2.insert into temp select * from emp;
3.insert into temp select * from temp;//自己给自己复制

//多表查询
select dname,dept.deptno,loc,count(*)as ‘人员数量’
from temp,dept
where temp.deptno=dept.deptno
group by deptno;
//from子查询
select dname,dept.deptno,loc,per_num
from dept,
(select count(*) as per_num,deptno from temp group by deptno) as tmp
where dept.deptno=tmp.deptno;
这里写图片描述
总结:
from子查询效率高于多表查询

删除表的重复记录

create table t1 (id int, name varchar(20));
insert into t1 values(100,’aaa’);
insert into t1 values(200,’bbb’);

1.创建一个空表,使得表结构与原表相同
create table t2 like t1;
2.导入不重复数据
insert into t2 select distinct * from t1;
3.删除原表
drop table t1;
4.将新表改名为原表
alter table t2 rename t1;
这里写图片描述

合并查询(合并多个select的查询结果,使用union,union all)

1.union(用于取得两个结果集的并集,并且会自动去掉结果集中的重复行)

例12.查找工资大于2500和职位为Manger的人

//union去重
select ename,sal,job from emp
where sal > 2500
union
select ename,sal,job from emp
where job=’MANGER’;
这里写图片描述

//union all不去重
select ename,sal,job from emp
where sal > 2500
union all
select ename,sal,job from emp
where job=’MANGER’;
这里写图片描述

外键(消除冗余数据)

外键定义主表和从表的关系,外键的约束主要定义在从表上,主表必须是有主键和唯一键。
当外键定义后,要求外键列数据必须在主表的主键列存在或者为null

语法:
foreign key(字段名) references 主表(列)

//主表
create table my_class (
id int primary key comment ‘班级id’,
name varchar(20)comment ‘班级姓名’
);

//从表
create table student(
id int primary key comment ‘学生id’,
name varchar(20) comment ‘学生姓名’,
class_id int,
foreign key(class_id) references my_class(id)
);

insert into my_class values(1,’15班’),(2,’16班’),(3,’17班’);
insert into student values(100,’张三’,1),(200,’李四’,2),(300,’王五’,3);

插入一个班级号为3的学生,没有这个班级,所以插入不成功
insert into student values(400,’赵六’,4);
这里写图片描述
但可以让班级id为null。
insert into student values(400,’赵六’,null);
这里写图片描述
总结:
主键不能为空,但外键可以为空。
但是不能存在外键有数据而对应的主表中不存在。

猜你喜欢

转载自blog.csdn.net/zwe7616175/article/details/80558664