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;//删除所有

 

posted @   白头吟  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示