一、CRUD简介

CURD是对数据库中的记录进行基本的增删改查操作:

  • C -> create 创建

  • R -> retrieve 读取

  • U -> update 更新

  • D -> delete 删除

二、create 新增

CURD是对数据库中的记录进行基本的增删改查操作

insert

insert into 表名 values(值,值)

2.1 指定列插入

2.1.1 单行数据全列插入

create table student(id bigint ,name varchar(50),gender varchar(20);
insert into student values (1,'秃然醒悟');

这个时候我们来查询一下是否插入成功:

SELECT * FROM student;

2.1.2 单行数据指定列插入

//只插入姓名和性别
insert into student (name,gender) values ('张三','男');
//只插入性别和id
insert into student (gender,id) values ('女',123123);


//查询一些表内
select * from student;

2.1.3 一次insert插入多个记录

insert into student values (3 ,'赵六' , '女') 
, (4 , '田七' , '男')
,(5 , '王五' , '女');

我们编译的时候,会提示我们当前操作影响到几行。就像我们现在插入三行那就是影响了三行。

通过这样的插入,只是客户端和服务器之间**只进行了一次网络通信**,如果我们分成三个insert来插入那我们就会有三次网络通信。

网络通信是有一定的开销的,所以我们的网络通好点会更好。

当然也可以针对某一列来插入多个记录:

insert into student (id) values (1),(2),(3);

三、查询

3.1 全列查询

把一个表的所有列和所有行全部查询

select * from 表名; 
//例如
select * from student;

此处select的* 的 *代表的是所有的列。

全列查询是一个非常危险的操作!!!,全列查询会把表中的所有数据都查询出来,会涉及到大量的硬盘访问和网络访问。

如果数据很大进行select * 的话,数据库服务器所在的极其的硬盘和网络瞬间会吃满,这样的话用户这边就会看到程序不能正常工作了。

3.2 指定列查询

比如一个几十个列,我们只需3个列就行。

select 列名,列名.... from 表名;


//例如
select id from student;
select id,name from student;

3.3 查询时带有表达式

一边查一边进行计算,进行简单的统计

create table exam(id bigint , 
name varchar(20),
chinese float comment '语文成绩',
math float COMMENT '数学成绩',
english float COMMENT '英语成绩');


--插入数据
insert into exam (name,chinese,math,english) values(1,'唐三藏', 67, 98, 56),
(2,'孙悟空', 87, 78, 77),
(3, '猪悟能',88,98,90),
(4, '曹孟德',82,84,67),
(5, '刘玄德',55,85,45),
(6, '孙权',70,73,78),
(7, '宋公明',75,65,30);

3.4 查询带有别名

select 表达式 as 别名 from 表名;
//例如
select Chinese + math + english as total from exam;

select name as '姓名' , Chinese + math + english as '总成绩' from exam;

3.5 针对查询结果去重

select distinct 列名 from 表名;
--例如我们来查询数学这一列有没有一样的
select distinct math from exma;

--注意,当指定多个列去重的时候要求多个列都是共同的值

当我们查询到有相同的值就会合并在一起。

3.6 条件查询

根据查询条件,对于查询的行进行筛选。条件处理,这一行作为查询结果;不成立则跳过。

3.6.1 比较运算符

  • value BETWEEN a0 AND a1:看value的值是否在[a0,a1]闭区间中

  • value IN :判断value是否在集合中

  • IS NULL / IS NOT NULL:列名<=>NUll列名 is NULL

  • LIKE : 模糊匹配

3.6.2 逻辑运算符

3.6.3 示例

3.6.3.1 基本查询

查询英语不及格的同学及英语成绩 (< 60)

--选择exam表里的name和English两列,判断是否小于60.
select name,english from exam where english < 60;

--也可以不用name,english
select name from exam where english < 60;--这样只会显示小于60的名字

本质上就是拿着表里的数据遍历,在遍历的同时就像条件判断。

3.6.3.2 查询语文成绩高于英语成绩的同学

//直显示语文分数高于英语分数的人的名字
select name from exam where chinese > english;

3.6.3.3 总分在 200 分以下的同学

select name,chinese,math,english from exam where chinese + math + english < 200;

但是注意下面这个写法

--这是错误的写法

select name,chinese+math+english as total from exam where total < 200;

原因如下(主要是条件判断的原理所决定的):

  1. 先遍历表格

  2. 取出表的每一行,带入条件 (这一块使用的别名)

  3. 把符合条件的行筛选出来

  4. 根据select后面指定的表达式进行计算 (这一块定义的别名)

3.6.3.4 AND和OR

  • 查询语文成绩大于80分且英语成绩大于80分的同学

3.6.3.x 模糊查询

like搭配通配符 -> %和__。

%代表任意个任意字符;__代表一个任意字符。

  • 查询所有姓孙的同学

select * from exam where name like '孙%';


--查找一个以孙结尾的同学
select * from exam where name like '%孙';

正则表达式:字符串匹配更广泛使用的方案(SQL不适用)。

通过特殊符号,定义了字符串的“筛选规则”。通过特殊字符定义筛选规则。

3.7 排序查询:

select 列名 from 表名 order by 列名 
--默认为升序排序  


--例如:在exam表里以Chinese为目标按照降序来排序
select * from exam order by chinese desc;

--先按照数学成绩从小到大排序,再按照英语
select * from exam order by math,english;

排序查询也是针对“临时表”操作的,不影响数据库服务器硬盘上存储的原始数据

默认是升序排序,也可以写asc来表示升序排序。降序排序是desc。

3.7.1 查询同学的总分,由高到低排序

select name,chinese + math + english  from exam order by chinese + math + english desc;

在order by中是可以使用别名作为排序规则的

select name,chinese + math + english as total from exam order by total desc;

区别于前面。order by执行顺序实在表达式计算之后的,别名先定义出来了再执行order by。

3.7.2 加入条件

先进行筛选再排序

--先筛选空再对语文排序
select name,chinese from exam where chinese is not NULL order by chinese;

3.8 分页查询

把所有数据存放在一页里展现出来:用户看不完,程序运行成本高。

这样我们就可以使用分页的效果来解决

select 列名 from 表名 where 条件 order by 列名 limit N;
--limit N; N是数字,约定这一页最多返回多少条记录
--limit子句来实现分页查询
--获取到前N条数据

--描述了从第M条记录开始(从0开始),往后获取N条记录
limit N offset M;--offset为“偏移量”,相当于“数组下标”

一页有三条数据:

select * from exam limit 3 offset 9;
--也可以这么写(不推荐)
select * from exam limit 9,3;

不会存在“下标越界”的情况,最多得到一个空

3.8.1 总成绩前三的同学

select name,chinese + math + english as total
from exam
where chinese is not NULL and math is not NULL and english is not NULL
order by total desc
limit 3;

四、update修改

4.1 语法

update 表名 set 列名 = 值 where条件/order by列名/limit N;

4.2示例

4.2.1 修改值

将孙悟空同学的数学成绩改成80

update exam set math = 80 where name = '孙悟空';
 --             这里的=相当于赋值了

update是修改的原始数据不是“临时表”!!

同时修改多个值:

4.2.2 多条件修改

把曹孟德的数学成绩改成60,语文成绩改成70

select exam set math = 60,chinese = 70 
where name = '曹孟德';

把总成绩倒数前三的三个同学的数学成绩加上30分

--我们先查询一下倒数前三的三个同学
select * from exam   
where chinese is not NULL and math is not NULL and english is not NULL 
order by chinese + english + math asc limit 3; 
--加上30分
update exam set math = math + 30;
where chinese is not NULL and math is not NULL and english is not NULL 
order by chinese + english + math asc limit 3; 

4.2.3 修改所有

给所有语文成绩翻倍

如果不指定任何条件就会针对所有的数据进行 修改

update exam set chinese = chinese * 2;

五、delete 删除

5.1 语法

delete from 表名 where条件/order by列名/limit N;

通过这些条件等子句限定要删除哪些内容,如果不写条件就会删除所有数据

5.2 示例

5.2.1 删除数据

delete from exam where name = '孙悟空';

delete from exam where math is null and chinese is null and english is null;
--删除表
delete from exam;

六、插入查询结果

把查询的结果插入到另一个表里

insert into 表名 select 列名 from 表名 ......;

6.1 示例

create table student (id int ,name varchar (20));
create table student2 (id int ,name varchar (20));

insert into student values (1,'张三'),(2,'李四'),(3,'王五');

--插入三行并且查询
insert into student2 select * from student;
--只插入name这一列并且只查询name
insert into student2 (name) select name from student;

七、聚合函数

聚合函数是为了进行聚合查询的。聚合函数可以理解为SQL的库函数

聚合查询就是再进行“行和列之间进行运算”。

  1. count ->查询到的数据的数量

  2. sum -> 必须是数字,求和

  3. avg -> 必须是数字,平均值

  4. max -> 必须是数字,最大值

  5. min -> 必须是数字,最小值

7.1 统计exam表记录

实际开发中,SQL一般会把建表和建库的操作写到以一个单独的文件中1,后续重新建表,直接把建表语句批量执行。

使用IDEA创建一个xxx.sql的文件,后续说。

7.2 COUNT

select count(*) from exam;
--这里面不要乱加空格

select count (*) from exam;
--这样SQL可能会以为count是个列名 (*)是别名

count只支持一个参数

--查询chinese这一列有行
select count(chinese) from exam;
--下面这个是错误的
select count(chinese,math) from exam;

注意:count(*)是可以把NULL也包含进去,但是count(列)就不能包含。

7.3 SUM

统计所有学生的数学总分

select sum(math) from exam;
--非数字的列只会得到NULL
select sum(name) from exam;

sum()里也可以是表达式:求所有学生总成绩的总成绩

select sum(chinese + math + english) from exam;

7.4 AVG

统计学生英语平均分:

select avg(english) from exam;

7.5 MAX和MIN

找出数学的最大值和英语的最小值

select max(math)

八、Group by 分组查询

把表的若干行进行分组,需要指定“分组依据”,指定某个列,这个列值相同的行就会分到一个组里。会根据分组后的结果进行聚合查询

8.1 语法

select 表达式 from 表名 group by 列名;

8.2 示例

先创一个新表

统计每个角色的人数

--先用name进行分组,再针对role这一列进行分组
select role , count(name) from emp group by role;

结果为3、2、1

统计每个角色的平均工资、最高工资、最低工资

select role , avg(salary),max(salary),min(salary)
from emp
grout by role;

8.3 having子句

分组之前指定条件:where

分组之后指定条件:having

--分组之后
--再group by的前面
--先针对原有的表进行筛选,把张三去掉。然后再执行下面的操作
select role,avr(salary) from emp where name != '张三' group by role;

统计每个岗位的平均薪资,保留平均薪资小于15000的人

--分组之前
--再group by的后面
--先聚合,把小于15000的人筛选出来后再操作
--也就是分组之后指定条件 
slelct role,avg(salary) from emp group by role having avg(salary) < 15000;

分组前的条件和之后的条件可以同时包含:统计每个岗位的平均薪资,先去掉张三,再保留平均薪资小于15000的人

select role,avg(salary) from emp where name != '张三' 
group by role having avg(salary) < 15000;

九、内置函数

9.1 日期函数

SQL中的函数调用一般都是通过select语句进行的,把函数放到select这里的列。查询结果就是函数调用返回的结果。

select curdate();--调用curdate函数,只包含年月日

--写列from表名之后就是再遍历表的每一行
select * from emp;
select curtime();--只显示时分秒
--显示年月日时分秒
select now();
--针对已有的时间日期进行提取操作
--先创建一个新的表
create table student(id int,name varchar(20),last_login_time datetime);
--插入数据
insert into student values(1,'张三','2026-01-28 15:56:00');
insert into student values(1,'张三',now());
--now()获取到的时间是系统时间
--展示一下
show student;

select name,date(last_login_time) from student; 
select adddate('2025-09-29',interval 3 day);
select adddate('2025-09-29',interval 3 month);
select adddate('2025-09-29',interval 3 year);
select adddate('2025-09-29',interval 3 week);
--计算日期差值
select datediff('2025-01-19','2026-01-28')

9.2 字符串函数

char_length和lenght:

--length(name):字数    char_lenght(name):字节数
select name,length(name),char_lenght(name) from student;

concat:

select concat(name,'同学') from student;
--多个
select concat(name,'同学','上次登录时间'+ last_login_time) from student;

concat_ws:

--带有分隔符的拼接
select concat_ws('|','a','b','c');

9.3 数学函数

9.4 其他函数