数据库基础二

数据库

二十、连接查询

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),

);

posted @ 2021-04-21 19:43  飞翔奥尔良烤翅  阅读(98)  评论(0)    收藏  举报