MYSQL-02课堂笔记
day02课堂笔记
1、把查询结果去除重复记录
注意:原表中数据不会被修改,只是查询结果去重
去重需要一个关键字:distinct
select distinct job from emp;
//这样编写是错误的,语法错误
//distinct只能出现再所有字段的最前方
select ename,distinct job from emp;
//distinct 出现再job,deptno两个字段之前,表示两个字段联合起来去重
select distinct job,deptno from emp;
统计工作岗位的数量
select count(distinct job) from emp;
2、连接查询
2.1、什么是连接查询?
从一张表中单独查询,称为单表查询
emp和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字
这种跨表查询,多张表联合起来查询数据,被称为连接查询
2.2、连接查询的分类?
根据语法的年代分类
SQL92:1992年出现的语法
SQL99:1999年出现的语法
根据表连接的方式分类
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,
这种现象被称为:笛卡尔积现象(数学现象)
select ename,dname from emp,dept;
会有56行记录
2.3、怎么避免笛卡尔积现象?
连接时加条件,满足这个条件的记录会被筛选出来!
select
ename,dname
from
emp,dept
where
emp.deptno=dept.deptno;
最终查询结果条数是14条,但是匹配过程中,匹配的次数减少了吗?
还是56次,只不过进行了四选一,次数没有减少
注意:通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的连接次数。
3、内连接
3.1、内连接---等值连接
案例:查询每个员工所在部门的名称,显示员工名和部门名?
emp e和dept d表进行连接,条件是:e.deptno=d.deptno
SQL92的语法
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
SQL92的缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面
SQL99的语法
select e.ename,d.dname from emp e join dept d where e.deptno=d.deptno;
SQL99的缺点:表连接的条件是独立的,连接之后,如果还需要进一步的筛选,再往后继续添加where
SQL99的语法
select ... from a join b on a和b的连接条件 where 筛选条件
3.2、内连接---非等值连接
案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;//条件不是一个等量关系,称为非等值连接
3.3、内连接---自连接
案例:查询员工的上级领导,要求显示员工名和对应的领导名?
技巧:将一张表看成是两张表
select
a.ename as '员工名' ,b.ename as '领导名'
from
emp a
join
emp b
on
a.mgr=b.empno;//员工的领导编号=领导的员工编号
13条记录,没有king(内连接)
以上就是内连接中的自连接,技巧:一张表看成是两张表
4、外连接
内连接:
select e.ename,d.dname from emp e join dept d where e.deptno=d.deptno;//内连接的特点:完成能够匹配上这个条件的数据查询处理
外连接(右外连接):
select e.ename,d.dname from emp e right join dept d where e.deptno=d.deptno;
select
e.ename,d.dname
from
emp e
right join
dept d
where
e.deptno=d.deptno;//外连接的特点:完成能够匹配上这个条件的数据查询处理,还要将主表中剩余的没有与副表中匹配的数据显示出来
外连接(左外连接):
select e.ename,d.dname from dept d left join emp e where e.deptno=d.deptno;
5、三张表怎么连接?
语法:
select ... from ... join b on a和b 的连接条件 join c on a和c 的连接条件 join d on a和d 的连接条件
一条SQL语句中内连接和外连接可以混合使用,都可以出现!
案例:找出每个员工的部门名称以及工资等级,
要求显示员工名,部门名,薪资,薪资等级?
select e.ename,d.deptno,s.grade from emp e join dept d on e.deptno=e.deptno join salgrade s on e.sal bewteen s.losal and hisal;
案例:找出每个员工的部门名称,以及工资等级,还有上级领导,
要求显示员工名、领导名、部门名、薪资,薪资等级
select e.ename,d.dname,e.sal,s.grade,t.ename from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and hisal left join emp t on e.mgr=t.empno;
6、子查询?
6.1、什么是子查询?
select语句中嵌套select语句,被嵌套的select语句被称为子查询。
6.2、子查询都可以出现在哪里呢
select ...(select) from ...(select) where ...(select)
6.3、where字句中的子查询
案例:找出比最低工资高的员工的姓名和工资
select
ename,sal
from
emp
where
sal<min(sal)
错误:where子句中不能直接使用分组函数。
实现思路:
第一步:查询最低工资是多少
select min(sal) from emp;
第二步:找出>800的
select ename,sal from emp where sal>800;
第三步:合并
select ename,sal from emp where sal>(select min(sal) from emp);
6.4、from 子句中的子查询
注意:from后面的子查询,可以将子查询的查询结果当作是一张临时表(子查询)
案例:找出每个岗位的平均工资的薪资等级
第一步:找出每个岗位i的平均工资
select job,avg(sal) from emp group by job;
第二步:克服心里障碍,把以上的查询结果当作是一张真实存在的表t
t表和s表进行表连接,条件:t表avg(sal) between s.losal and s.hisal;
select t.*,s.grade from (select job,avg(sal) as avgsal from emp group by job) t join salgrade s on t.avgsal between s.losal and s.hisal;
6.5、select 后面出现的子查询(了解即可)
案例:找出每个员工的部门名称,要求显示员工名,部门名?
select e.ename ,(select d.dname from dept d where e.deptno=d.deptno) as dname from emp e;
select e.ename ,(select d.dname from dept ) as dname from emp e;
错误:对于select 后面的子查询来说,这个子查询只能一次返回一条结果
多于一条,就报错!
7、union合并查询结果集
案例:查询工作岗位是manager和salesman的员工?
select ename, job emp where job='manager' or job='saleman'; select ename,job from emp where job in('manager','salesman');
使用union
select ename,job from emp where job='manager' union select ename,job from emp where job='salesman';
union的效率要高一些,对于表连接来说,每连接一次新表
则匹配的次数满足笛卡尔积,成倍的翻。。。
但是union可以减少匹配的次数,在减少匹配的情况下
还可以完成两个结果的拼接
a 连接 b 连接 c
a 10条记录
b 10条记录
c 10条记录
匹配次数是:1000
a 连接 b 一个结果:10*10-->100次
a 连接 c 一个结果:10*10 -->100次
使用union的话是:100 +100=200(union把乘法变成了加法运算)
union在使用的时候有注意事项?
1.union在进行结果集合并的时候,要求两个结果集的列数相同
select ename,job from emp where job='manager' union select ename from emmp where job='salesman';
2.要求:结果集合并列与列的数据类型也要相同
select ename,job from emmp where job='manager' union select ename,sal from emp where job='salesman';
8、limit
8.1、limit的作用:将查询结果集的一部分取出来 通常使用在分页查询当中
百度默认:一页显示10条记录。
分页的作用:为了提高客户的体验,因为一次全部都查出来,用户提样差
可以一页一页的翻着看
8.2、limit怎么用呢?
完整用法:limit startIndex,length
缺省用法:limit 5;这里取前五;
按照薪资降序,取出排在前五的员工?
select ename,sal from emp order by sal desc limit
5; select ename,sal from emp order by sal desc limit
0,5;
8.3、注意:MySQL当中的limit在order by 之后执行!!!!
8.4、取出工资排名在【3-5】名的员工?
select ename,sal from emp order by sal desc limit 2,3
2表示起始位置从下标2开始,就是第三条记录
3表示长度
8.5、取出工资排名在【5-9】名的员工?
select ename,sal from emp order by sal desc limit 4,5;
8.6、分页
每页显示3条记录
第一页:limit 0,3 [0 1 2]
第二页:limit 3,3 [3 4 5]
第三页:limit 6,3 [6 7 8]
第四页:limit 9,3 [9 10 11]
每页显示pageSize条记录
第pageNo页:limit (pageNo-1) *pageSize, pageSize
public static void main(String [] args){
//用户提交一个页码,以及每页显示的记录条数
int pageNo =5;//第五页
int pageSize=10;//每页显示10条
int startIndex=(pageNo-1)*pageSize;
String sql="select ... limit "+startIndex+","+pageSize;
}
记公式:
limit (pageNo-1)*pageSize,pageSize
9、关于DQL语句的大总结
select ... from ... where ... group by .... having ... order by ... limit ...
执行顺序:
1.from
2.where
3.group by
4.having
5.select
6.order by
7.limit ..
10、表的创建(建表)
10.1建表的语法格式(建表属于DDL语句,DDL语句包括:create drop alter)
create table 表名(字段名 数据类型,字段名2 数据类型, 字段名3 数据类型);
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型
);
表名:建议以t_或者tbl_开始,可读性强,见名知意
字段名:见名知意。
表名和字段名都属于表示符。
10.2、关于mysql中的数据类型?
很多数据类型,我们只需要掌握一些常见的数据类型即可。
varchar(最长255)
可变长度的字符串
比较智能,节省空间
会根据实际的数据长度动态的分配空间
优点:节省空间
缺点:需要动态的分配空间,速度慢
char(最长255)
定长字符串
不管实际的字符长度是多少
分配固定长度的空间取存储数据
使用不当的时候,可能会造成空间的浪费
优点:不需要动态的分配空间,速度快
缺点:使用不当会造成空间的浪费
varchar 和char我们怎么选择?
性别字段你选什么?因为性别是固定长度的字符串,所以选择char
姓名字段选什么?每个人的名字长度不同,所以你选择varchar
int (最长11)
数字中的整型,等同与java中的int
bigint
数字中的长整型,等同于Java中的long
float
单精度浮点型
double
双精度浮点型
date
短日期类型
datetime
长日期类型
clob
字符大对象
最多可以存储4G的字符串
比如:存储一篇文章,存储一个说明
blob
二进制大对象
Binary Large OBject
专门用来存储图片,声音,视频等流媒体。
你需要使用IO流才行
7.3、创建一个学生表?
学号,姓名,年龄,性别,邮箱地址
create table t_student{ no int, name varchar(32), sex char(1), age int(3), email varchar(255) };
删除表
drop table t_student;//当这张表不存在时会报错! drop table if exits t_student;//如果这张表存在的话,删除
7.4、插入数据insert(DML)
语法格式:
insert into 表名(字段名1,字段名2,字段名3……) values(值1,值2,值3);
注意:字段名和值要一一对应,数量要相同,数据类型要对应。
insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m',20,'zhangsan@123'); insert into t_student(no) values(3); insert into t_student(name) values('wangwu');
注意:insert语句但凡是执行成功了,那么必然会多一条记录
没有给其他字段指定值的话,默认值为null
也可以设置默认值
drop table if exits t_student; create table t_student( no int, name varchar(32), sex char(1) default 'm', age int(3), email varchar(255) ); insert into t_student(no) values(1);
//注意:前面的字段名省略的话,等于都写上了,所有值也要都写上!
insert into t_student values(2);//错误
insert into t_student values(2,'lisi','f',20,'lisi@123.com');
7.5、insert 插入日期
数字格式化:format
格式化数字:format(数字,'格式')
select ename,format(sal,'$ 999.999') as sal from emp;
str_to_date:将字符串varchar类型转换成date类型
date_format:将date类型转换成一定格式varchar类型
drop table if exits t_user; create table t_user( id int, name varchar(32), birth date//生日使用字符串,没问题 );
注意:数据库中的一条命名规范:
所有的标识符都是全部小写的,单词和单词之间使用下划线进行衔接
插入数据?
insert into t_user(id,name,birth) values(1,'zhangsan','01-10-1990');//1990年10月1日
出问题:原因是类型不匹配,数据库birth是date类型,这里给了一个字符串varchar
怎么办?可以使用str_to_date函数进行类型匹配。
str_to_date函数可以将字符串转换成日期类型date?
语法格式:
str_to_date('字符串日期','日期格式')
mysql的日期格式:
%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒
insert into t_user(id,name,birth) values(1,'zhangsan',str_to_date('01-10-1990','%d-%m—%Y'));
str_to_date函数可以把字符串varchar转换成date类型
通常使用在插入insert方面,因为插入的时候需要一个日期类型的数据
需要通过该函数将字符串转换成date
如果你提供的日期是:%Y-%m-%d这个格式,str_to_date函数就不需要了!!!
insert into t_user(id,name,birth) values(2,'lisi','1990-10-01');
查询的时候可以以某个特定的日期格式展示吗?
date_format
这个函数可以将日期类型转换成特定格式的字符串。
select id,name,date_format(birth,'%m%d%Y' ) as birth from t_user;
date_format函数怎么用?
date_format(日期类型数据,'日期格式')
这个函数通常使用在查询日期方面,设置展示的日期格式
select id ,name ,birth from t_user;
以上的SQL语句实际上是进行了默认的日期格式化。
自动将数据库中的date类型转换为varchar类型
并且采用的格式是mysql默认的日期格式:%Y-%m-%d
7.6、date和datetime两个类型的区别?
date是短日期:只包含年月日信息
datetime是长日期:包括年月日时分秒信息
drop table if exits t_user; create table t_user( id int, name varchar(32), birth date, create_time datetime );
mysql短日期默认格式:%Y-%m-%d
mysql长日期默认格式:%Y-%m-%d %h:%i:%s
在MySQL中怎么获取系统当前时间?
now()函数,并且获取的时间带有:时分秒信息!!!是datetime类型的
insert into t_user(id,name,birth,create_time) values(2,'lisi','1990-10-01',now()); insert into t_user(id,name,birth,create_time) values(2,'lisi','1990-10-01','2022-01-10 13:09-01');
10.7、修改update(DML)
语法格式:
update 表名 set 字段名=值1,字段名=值2,字段名=值3…… where条件
注意没有条件限制会导致所有的数据更新
update t_user set name='jack',birth='2000-10-11' where id=2;
更新所有?
update t_user set name='abc';
10.8、删除数据delete(DML)
语法格式:
delete from 表名 where 条件;
注意:没有条件,整张表的数据会被全部删除!
delete from t_user where id=2; insert into t_user(id) values(2); delete from t_user;//删除所有
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~