数据库基础二
数据库
二十、连接查询
1、什么是连接查询?
在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。
stuno stuname classno classname
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 张三 1 北京大兴区亦庄经济技术开发区第二中学高三一班
2 李四 1 北京大兴区亦庄经济技术开发区第二中学高三一班
...................................................
学生和班级信息存储到一张表中,结果就像上面一样,数据会存在大量的重复,导致数据的冗余。
2、连接查询的分类?
根据语法出现的年代来划分的话,包括:
SQL92(一些老的DBA可能还在使用这种语法。DBA:DataBase Administrator,数据库管理员)
SQL99(比较新的语法)
根据表的连接方式来划分,包括:
内连接:等值连接、非等值连接、自连接
外连接:左外连接、右外连接
全连接(很少用)
3、在表的连接查询方面有一种现象被称为:笛卡尔积现象(笛卡尔乘积现象)
找出每一个员工的部门名称,要求显示员工名和部门名。
笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。
关于表的别名:
select e.ename,d.dname from emp e,dept d;
表的别名有什么好处?
第一:执行效率高。
第二:可读性好。
4、怎么避免笛卡尔积现象?
当然是加条件过滤 。虽然避免了笛卡尔积现象,但是匹配次数没有变少,只不过显示的是有效记录。
找出每一个员工的部门名称,要求显示员工名和部门名
select e.ename,d.dname from emp e,dept d where e.deptno =d.deptno; //SQL92
5、内连接之等值连接,最大特点是:条件是等量关系。
查询每个员工的部门名称,要求显示员工名和部门名
SQL92:(太老了)
select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno;
SQL99:(常用的)
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno;
语法:
............
A
inner join (inner可以省略,带着inner的目的是可读性好一些)
B
on
连接条件
where
.......
SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了
6、内连接之非等值连接,最大特点是:连接条件中的关系是非等量关系。
找出每个员工的工资等级,要求显示员工名、工资、工资等级
select
e.ename,e.sal,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal;
7、自连接,最大特点是:一张表看做两张表,自己连自己。
找出每个员工的上级领导,要求显示员工名和对应的领导名
员工的领导编号 = 领导的员工编号
select
a.ename,b.ename
from
emp a
inner join
emp b
on
a.mgr = b.empno;
8、什么是外连接?和内连接有什么区别?
内连接:
假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。AB两张表没有主副之分,两张表是平等的。
外连接:
假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表。当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。
左外连接(左连接):表示左边的这张表是主表
右外连接(右连接):表示右边的这张表是主表
找出每个员工的上级领导,所有员工都必须查询出来
内连接:
select
a.ename'员工',b.ename'员工‘
from
emp a
join
emp b
on
a.mgr = b.empno;
//此时在员工表的领导会因为无上级而不显示
外连接:(左)
select
a.ename '员工',b.ename'领导'
from
emp a //此表为主表
left join // left outer join 中的outer可以省略
emp b
on
a.mgr = b.empno;
外连接:(右)
select
a.ename '员工',b.ename'领导'
from
emp b
right join
emp a //此表为主表
on
a.mgr = b.empno;
9、三张表怎么连接查询?
找出每一个员工的部门名称以及工资等级
语法:
...............
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,e1.ename'领导'
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;
二十一、子查询
1、什么是子查询?子查询都可以出现在哪里?
select语句当中嵌套select语句,被嵌套的select语句是子查询
子查询可以出现在哪里?
select
.....(select)
from
......(select)
where
......(select)
2、where子句中使用子查询
找出高于平均薪资的员工信息
select * from emp where sal >avg(sal); //错误的写法,where后面不能直接使用分组函数
第一步:找出平均薪资
select avg(sal) from emp;
第二步:where过滤
select * from emp where sal >2073.214286;
两步合起来的写法:
select * from emp where sal >(select avg(sal) from emp);
3、from后面嵌套子查询
找出每个部门平均薪水的薪资等级
第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) as avgsal from emp group by deptno;
第二步:将以上的查询结果当成临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal
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,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
第二步:基于以上结果,继续按照deptno分组,求grade平均值
select
e.ename,e.sal,e.deptno,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
group by
e.deptno;
4、select后面嵌套子查询
找出每个员工所在的部门名称,要求显示员工名和部门名
select
e.ename,e.deptno,
(select d.dname from dept d where e.deptno = d.deptno) as dname
from
emp e;
二十二、union(可以将查询结果相加)
找出工作岗位是SALESMAN和MANAGER的员工
第一种:
select ename,job from emp where job ='MANAGER' or job ='SALESMAN';
第二种:
select ename,job from emp where job in('MANAGER','SALESMAN');
第三种:
select ename,job from emp where job ='MANAGER'
union
select ename,job from emp where job ='SALESMAN';
二十三、limit(分页查询都靠它)
limit是MySQL特有的,其他数据库没有,不通用
语法:
limit startIndex, length
startIndex表示起始位置
length表示取几个
取出工资前5名的员工(思路:降序取前5个)
select ename,sal from emp order by sal desc;
取前5个:(两种写法)
select ename,sal from emp order by sal desc limit 0,5;
select ename,sal from emp order by sal desc limit 5;
limit是sql语句最后执行的一个环节:
select //5
...............
from //1
...............
where //2
..............
group by //3
.............
having //4
............
order by //6
...........
limit //7
............;
找出工资排名在第4到第9名的员工
select ename,sal from emp order by sal desc limit 3,6;
通用的标准分页SQL:
每页显示3条记录:
第一页:0,3
第二页:3, 3
第三页:6, 3
第四页:9,3
第五页:12, 3
每页显示pageSize条记录:
第pageNo页:(pageNo-1)*pageSize, pageSize
二十四、创建表:
建表语句的语法格式:
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,
........................
);
常见的MYSQL当中字段的数据类型
int 整数型(java中的int)
bigint 长整型(java中的long)
float 浮点型(java中的float double)
char 定长字符串(String)
varchar 可变长字符串(StringBuffer/StringBuilder)
date 日期类型(对应java中的java.sql.Date类型)
BLOB 二进制大对象(存储图片、视频等流媒体信息)Binary Large OBject(对应java中的object)
CLOB 字符大对象(存储较大文本,比如,可以存储4G的字符串)
Character Large OBject(对应java中的object)
char和varchar怎么选择?
在实际开发中,当某个字段中的数据长度不发生改变的时候,是定长的。例如:性别、生日等都是采用char。
当一个字段的数据长度不确定,例如:简介、姓名等都是采用varchar。
表名在数据库中一般建议以:t_或者tbl_开始
创建学生表:
学生信息包括:
学号、姓名、性别、班级编号、生日
学号:bigint
姓名:varchar
性别:char
班级编号:int
生日:char
create table t_student(
no bigint,
name varchar(255),
sex char(1),
classno varchar(255),
birth char(10),
);

浙公网安备 33010602011771号