MySQL DML 与 DQL 语句详解

本篇主要讲解 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 注意事项

  1. 值的顺序必须和字段顺序一一对应;
  2. 字符串、日期必须用单引号包裹;
  3. 特殊字符使用\转义;
  4. 值类型、范围要和字段定义匹配。

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 (字段) 区别

  1. count(*):统计所有行,包含 NULL 行;
  2. count(1):统计所有行,包含 NULL 行;
  3. 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;
相关推荐
codeejun1 小时前
每日一Go·MySQL-9、索引存储结构|页分裂、页合并、索引高度与磁盘
数据库·mysql
Pniubi1 小时前
事务(Spring&MySQL)
数据库·sql·spring
孔令飞2 小时前
1024程序员节,OneX平台送3套免费Go实战项目
云原生·go·ai编程
bksczm2 小时前
Shardingsphere安装
mysql·shardingsphere
吴声子夜歌2 小时前
Docker入门与实战——常见问题总结
运维·docker·容器
是jin奥2 小时前
最新 FFmpeg 安装脚本:Linux x86_64
linux·运维·ffmpeg
丨晨 丨2 小时前
K8s控制器天团图鉴-五大控制器整活
云原生·容器·kubernetes
DBA_G2 小时前
GBase 8a MPP集群个人电脑安装环境浅析
数据库
小林ixn2 小时前
别再 MySQL + Milvus 双写了:PostgreSQL + pgvector 一张表搞定 AI 长期记忆
数据库·postgresql·agent