写在最前面:本博文如有错误,还望大家指出,谢谢
MySQL数据库复习(1)----单表查询sql语句
MySQL数据库复习(3)------约束
MySQL数据库复习(4)----存储引擎,事务,索引,视图和设计三范式
在实际开发中,大部分都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
一般一个业务都会对应多张表,比如:学生表和班级表
如果学生和班级信息都存到一张表中,会导致数据存在大量的重复,浪费空间
根据语法出现的年代划分:SQL92,SQL99
根据表的连接方式来划分:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全连接(很少用)
在表的连接查询方面有一种现象被称为:笛卡尔积现象
笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积
例:select e.ename,d.dname from emptable e,dept d;
好处:执行效率高,可读性好
加条件进行过滤
避免了笛卡尔积现象不会减少记录的匹配次数,只不过显示的是有效记录
例:找出每一个员工的部门名称,要求显示员工名和部门名
select e.ename,d.dname from emp e, dept d where e.deptno = d.deptno;
最大的特点是:条件是等量关系
例:找出每一个员工的部门名称,要求显示员工名和部门名
SQL92:(不常用)
select e.ename,d.dname from emp e, dept d where e.deptno = d.deptno;
SQL99:(常用的)
这里的inner可以省略,带着inner可读性好一些
select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno;
语法:
…
A
join
B
on
连接条件
where
…
SQL99语法结构更清晰,表的连接条件和后面的where条件分离了
最大的特点是:连接条件中的关系是非等量关系
案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.local and s.hisal;
最大特点是一张表看作两张表,自己连接自己
例:找出每个员工的上级领导,要求显示员工名和对应的领导名
条件:员工的领导编号 = 领导的员工编号
select a.ename as ‘员工名’,b.ename as ‘领导名’ from emp a inner join emp b on a.mgr = b.empno;
什么是外连接?和内连接有什么区别?
内连接:假设A和B表进行连接,使用内连接,将A表和B表能够匹配上的记录查询出来,这就是内连接。AB两张表没有主副之分
外连接:假设A表和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中数据,捎带查询副表数据,当副表中的数据没有和主表中的数据匹配上的话,副表自动模拟出NULL与之匹配
左外连接(左连接):表示左边的这张表是主表
右外连接(右连接):表示右边的这张表是主表
左连接有右连接的写法,右连接也有对应的左连接的写法
例:找出每个员工的上级领导,要求显示员工名和对应的领导名
(每个员工都要显示)
左外连接(outer可以省略):
select a.ename as ‘员工名’,b.ename as ‘领导名’ from emp a left outer join emp b on a.mgr = b.empno;
在这里a是主表,b是副表
右外连接(outer可以省略):
select a.ename as ‘员工名’,b.ename as ‘领导名’ from emp b right outer join emp a on a.mgr = b.empno;
a是主表,b是副表
外连接最重要的特点是:主表的数据无条件的全部查询出来
例:找出每一个员工的部门名称以及工资等级
注意:
…
A join B join C on …
表示A表与B表先进行表连接,连接之后A表继续和C表进行连接。
select e.ename,d.dname,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal;
例:找出每一个员工的部门名称、工资等级、上级领导
select e.ename,d.dname,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp e1 on e.mgr = e1.empno;
select语句当中嵌套select语句,被嵌套的select语句是子查询
出现位置:
select …(select) from …(select) where …(select)
例:找出高于平均薪资的员工信息
select * from emp where sal > (select avg(sal) from emp);
例:找出每个部门平均薪水的薪资等级
第一步:找出每个部门的平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) as avgsal from emp group by deptno;
第二步:将以上的查询结果当作临时表t,将这个临时表t和salgrade 表连接,条件是 avgsal between s.losal and s.hisal
select t.*,s.grade from t join salgrade s on t.avgsal between s.losal and s.hisal;
因此最终的sql语句为:
select t.*,s.grade from (select deptno,avg(sal) as avgsal from emp group by deptno) t join salgrade s on t.avgsal between s.losal and s.hisal;
例:找出每个员工所在的部门名称,要求显示员工名和部门名
select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
select ename,job from emp where job = ‘manager’
union
select ename,job from emp where job = ‘salesman’;
Oracle中有一个相同的机制,叫做rownum
limit startIndex, length
startIndex表示起始位置(从0开始),length表示取几个
例:取出工资前5名的员工
select ename,sal from emp order by sal desc limit 0, 5;
select ename,sal from emp order by sal desc limit 5;
默认从0开始
例:每页显示三条记录
第一页:0,3
第二页:3,3
第三页:6,3
每页显示size条记录,公式为:
第no页:(no-1)*size,size
create table 表名(
字段名 数据类型 约束,
字段名 数据类型 约束,
……
);
int bigint double float char varchar date
blob:二进制大对象,存储图片视频等
clob:字符大对象,存储较大文本
表名在数据库中一般建议以:t_或者tbl_开始
insert into 表名(字段名,字段名…)values(值,值……)
要求字段和值一一对应
注意:当一条insert语句执行成功之后,表格当中必然会多一条记录
insert into t_student values(1,2,’lisi’);
insert into t_student(no,name,sex) values(1,’lisi’,0),(2,’zhangsan’,1);
语法:
create table 表名 as select语句;
将查询结果当作表创建出来
insert into dept1 select * from dept;
语法格式:update 表名 set 字段名=值,字段名=值… where 条件;
注意:没有条件整张表全部更新
语法格式:
delete from 表名 where 条件;
注意:没有条件全部删除
truncate table emp1;
表被截断,不可回滚。永远丢失
本笔记网课来源
https://www.bilibili.com/video/BV1fx411X7BD