本篇主要讲解 MySQL 中DML 数据操作语言(增删改) 和DQL 数据查询语言(查询),包含语法、实操案例、易错点、生产注意事项,适合入门复习、面试备考。
一、SQL 语言分类简介
- DML(Data Manipulation Language) :数据操作语言,负责表内数据增、删、改 ;关键字:
insert、update、delete - DQL(Data Query Language) :数据查询语言,负责数据查询 ;关键字:
select
补充区分:DDL(create/alter/drop)操作表结构,DML 操作表数据。
二、DML 数据操作语言(增删改)
2.1 INSERT 插入数据 & REPLACE
insert:向数据表添加记录,支持单条、批量、指定字段插入。
语法
-- 1. 全字段插入单条
insert [into] 表名 values (值1, 值2......);
-- 2. 指定字段插入单条
insert [into] 表名 (字段1,字段2......) values (值1,值2......);
-- 3. 批量插入
insert [into] 表名 values (值1,值2...),(值1,值2...);
insert [into] 表名 (字段1,字段2) values (值1,值2),(值1,值2);
实操示例
-- 创建测试表
create table student2(
id int primary key,
name varchar(30) not null,
sex char(2) default '女' ,
birthday date
);
-- 全字段插入
insert into student2 values (1001,'李成峰','男','2000-10-1');
-- 指定字段插入,sex会使用默认值女,birthday为NULL
insert into student2 (id,name) values (1002,'薛佳颖');
-- 批量插入,into可以省略,now()获取当前时间
insert student2 values
(1003,'孙德胜','男','1998-12-31'),
(1004,'凤飞飞','女','2009/3/15'),
(1005,'张无忌','男',now());
INSERT 注意事项
- 值的顺序必须和字段顺序一一对应;
- 字符串、日期必须用单引号包裹;
- 特殊字符使用
\转义; - 值类型、范围要和字段定义匹配。
REPLACE 语句
replace 和 insert 用法基本一致,区别:主键 / 唯一键冲突时,先删除原有行,再插入新行 ,等价于 delete + insert。
-- 主键冲突,直接insert会报错
insert student2 values (1005,'尹志平','男','1235-9-1');
-- replace:冲突则覆盖
replace student2 values (1005,'尹志平','男','1235-9-1');
⚠️ 注意:删除原有数据不能违反外键约束。
2.2 UPDATE 修改数据
语法
update 表名 set 字段1=值1,字段2=值2,... [where 条件];
示例
-- 修改id=1002的生日
update student2 set birthday = '2012-12-12' where id=1002;
✅ 重点坑点 :不加
where会全表更新 ,生产环境严禁裸写update!
-- 危险语句!整张表birthday全部改成当前时间
update student2 set birthday = now();
生产表通常设计
update_time字段,修改数据时同步更新为now()记录更新时间。
2.3 DELETE 和 TRUNCATE 删除数据
语法
delete from 表名 [where 条件];
truncate table 表名;
示例
-- 删除指定id记录
delete from student2 where id = 1005;
事务回滚演示(InnoDB 引擎)
delete 支持事务,可以回滚恢复:
start transaction; -- 开启事务
delete from student2 where id = 1001;
select * from student2;
rollback; -- 撤销删除,恢复数据
commit; -- 提交事务,提交后无法回滚
DELETE / TRUNCATE / DROP 三者对比(面试高频)
| 语句 | 作用 | 能否回滚 | 速度 | 表结构 |
|---|---|---|---|---|
| delete | 删除表中部分 / 全部数据 | ✅ 支持事务回滚 | 慢 | 保留 |
| truncate | 清空整张表所有数据 | ❌ 不可回滚 | 很快 | 保留 |
| drop | 删除整张表 | ❌ 不可回滚 | 最快 | 删除 |
补充:delete 只能删除整行记录 ,不能单独清空某个字段;想要清空字段值,用
update 表 set 字段=null。
三、DQL 数据查询语言(select)
DQL 用来查询数据表数据,是开发里使用最多的 SQL。 完整语法顺序:
select 字段列表
from 表名列表
where 条件列表
group by 分组字段列表
having 分组后条件列表
order by 排序字段列表
limit 分页参数
⭐ SQL 执行顺序(非常重要)
from → where → group by → having → select → distinct → order by → limit
关键点:where 在分组前过滤;having 在分组后过滤;聚合函数不能写在 where 中。
3.1 基础查询
-- 查询所有字段,生产不推荐*
select * from student3;
-- 查询指定字段(推荐写法)
select name,chinese,math,english from student3;
-- 字段起别名,as可以省略
select name as '姓名', chinese '语文' from student3;
-- distinct 去重,写在最前面,多字段是组合去重
select distinct name,english from student3;
3.2 条件查询 where
select 字段列表 from 表名 where 条件;
常用运算符与示例
-- 大于、小于
select name,english from student3 where english>90;
-- between and 闭区间
select * from student3 where english between 80 and 90;
-- in 匹配多个值
select * from student3 where math in (85,90);
-- like模糊查询:%任意字符,_单个字符
select name from student3 where name like "李%"; -- 李开头
select * from student3 where name like "__"; -- 两个字姓名
-- NULL判断:不能用=,用is null / is not null,<=>安全等于
select * from student3 where chinese is NULL;
-- regexp正则匹配
select * from student3 where id regexp "^9";
MySQL 中
+只有数字加法功能,不会拼接字符串;字符串转数字失败则转为 0;NULL 参与运算结果一定是 NULL。
3.3 聚合函数(纵向统计)
常用聚合函数:count、sum、avg、max、min
规则:NULL 不参与聚合函数计算;聚合函数不能放在 where 后面
-- 总行数
select count(*) from student3;
-- 平均分,保留别名
select avg(chinese) "语文平均分",avg(math) "数学平均分" from student3;
-- 条件聚合
select avg(english) "女生英语平均分" from student3 where gender="女";
count (*) /count (1) /count (字段) 区别
count(*):统计所有行,包含 NULL 行;count(1):统计所有行,包含 NULL 行;count(字段):只统计该字段不为 NULL 的行; 效率优先级:有主键时count(主键)>count(1)>count(普通字段)。
3.4 分组查询 group by
作用:把相同字段值的数据分为一组,配合聚合函数统计。 语法:
select 字段,聚合函数 from 表名
[where 分组前过滤]
group by 分组字段
[having 分组后过滤];
规范:select 后面非聚合的字段,必须写在 group by 中!
示例:
-- 按班级分组,求平均分,round保留2位小数
select class_id as '班级编号', round(avg(score),2) as '平均成绩'
from transcript
group by class_id;
-- 分组后过滤:只保留平均分≥90的班级
select class_id "班级", avg(score) "平均分"
from transcript
group by class_id
having avg(score)>=90;
-- where + having 组合:先过滤85分以下成绩,再分组,再过滤平均分<90班级
select class_id "班级", avg(score) "平均分"
from transcript
where score>85
group by class_id
having avg(score)>90;
where 和 having 对比
- where:分组之前过滤原始行,不能写聚合函数;
- having:分组之后对聚合结果过滤,可以使用聚合函数。
3.5 排序 order by
order by 字段1 [asc|desc], 字段2 [asc|desc];
-
asc:升序,默认;desc:降序 -
多字段:先按第一个字段排序,值相同再按第二个字段排序
-- 数学降序
select * from student3 order by math desc;
-- 中文按GBK排序(解决中文乱序)
select * from student3 order by convert(name using gbk) asc;
-- 组合排序:性别升序,同性别语文降序
select * from student3 order by convert(gender using gbk) asc,chinese desc;
3.6 分页查询 limit
偏移量从 0 开始! 三种写法:
-- limit 偏移量,条数
select * from student3 limit 2,3;
-- limit 条数,默认偏移0
select * from student3 limit 3;
-- limit 条数 offset 偏移量(可读性更好,推荐)
select * from student3 limit 3 offset 2;