MySQL-基础查询(下)

目录

[一、数据更新:Update 的灵活用法](#一、数据更新:Update 的灵活用法)

[1. 单字段 / 多字段更新](#1. 单字段 / 多字段更新)

(1)更新单个字段

(2)更新多个字段

[2. 基于原数据的更新](#2. 基于原数据的更新)

[3. 全表更新(谨慎使用!)](#3. 全表更新(谨慎使用!))

[二、数据删除:Delete vs Truncate](#二、数据删除:Delete vs Truncate)

[1. Delete:删除部分 / 全表数据](#1. Delete:删除部分 / 全表数据)

(1)删除指定数据

(2)删除全表数据

[2. Truncate:截断表(重置表)](#2. Truncate:截断表(重置表))

[Delete vs Truncate 对比表](#Delete vs Truncate 对比表)

三、插入查询结果:去重数据的小技巧

四、聚合函数:统计数据的利器

[1. Count:计数](#1. Count:计数)

[2. Sum/Avg:求和 / 平均值](#2. Sum/Avg:求和 / 平均值)

[3. Max/Min:最大 / 最小值](#3. Max/Min:最大 / 最小值)

[五、分组查询:Group By + Having](#五、分组查询:Group By + Having)

[1. 基础分组统计](#1. 基础分组统计)

[2. 多字段分组](#2. 多字段分组)

[3. Having 筛选分组结果](#3. Having 筛选分组结果)

总结

[MySQL 语法速查表](#MySQL 语法速查表)

注意


上一篇我们讲了 MySQL 的基础查询,今天继续深入 ------ 从数据更新(Update)数据删除(Delete/Truncate)聚合函数分组查询(Group By),这些都是日常开发中高频使用的进阶操作。

一、数据更新:Update 的灵活用法

update用于修改表中已有的数据,核心语法是update 表名 set 列=值 [where 条件],下面看几个实用案例。

1. 单字段 / 多字段更新

(1)更新单个字段

比如把 "孙悟空" 的数学成绩改成 80 分:

sql 复制代码
-- 先查原数据
select name, math from exam_result where name = '孙悟空';
-- 更新数据
update exam_result set math = 80 where name = '孙悟空';
-- 验证结果
select name, math from exam_result where name = '孙悟空';
(2)更新多个字段

同时修改 "曹孟德" 的数学和语文成绩:

sql 复制代码
update exam_result set math = 60, chinese = 70 where name = '曹孟德';

2. 基于原数据的更新

如果要在原字段值基础上修改(比如 "给总分倒数前三的同学数学 + 30 分"),可以直接用字段做运算:

sql 复制代码
-- 给总分倒数前三的同学数学+30分
update exam_result set math = math + 30
order by chinese + math + english limit 3;

注意:MySQL 不支持math += 30这种写法,必须显式写math = math + 30

3. 全表更新(谨慎使用!)

如果省略where条件,会更新整个表的对应字段,比如把所有同学的语文成绩翻倍:

sql 复制代码
-- 全表更新,风险高!
update exam_result set chinese = chinese * 2;

二、数据删除:Delete vs Truncate

删除数据有两种常用方式:deletetruncate,两者区别很大,一定要分清楚。

1. Delete:删除部分 / 全表数据

deleteDML 语句 ,可以删除部分数据(加where)或全表数据,支持事务回滚。

(1)删除指定数据

比如删除 "孙悟空" 的考试成绩:

sql 复制代码
delete from exam_result where name = '孙悟空';
(2)删除全表数据
sql 复制代码
-- 删除for_delete表的所有数据
delete from for_delete;

delete删除全表后,自增主键不会重置(比如原主键到 3,删除后插入新数据主键从 4 开始)。

2. Truncate:截断表(重置表)

truncateDDL 语句,只能删除全表数据,且不可回滚,但执行速度更快,会重置自增主键。

sql 复制代码
-- 截断for_truncate表
truncate table for_truncate;
-- 插入新数据,主键从1开始
insert into for_truncate (name) values ('d');

Delete vs Truncate 对比表

特性 Delete Truncate
操作类型 DML(数据操作语言) DDL(数据定义语言)
能否删部分数据 可以(加 where) 只能删全表
自增主键 不重置 重置为初始值
事务回滚 支持 不支持
执行速度 较慢(逐行删除) 较快(直接重置表)

三、插入查询结果:去重数据的小技巧

如果要把一张表的去重数据 插入另一张表,可以用insert into ... select ...语法,比如给重复数据去重:

sql 复制代码
-- 1. 创建空表,结构和原表一致
create table no_duplicate_table like duplicate_table;
-- 2. 插入原表的去重数据
insert into no_duplicate_table select distinct * from duplicate_table;
-- 3. 重命名表,替换原表
rename table duplicate_table to old_table, no_duplicate_table to duplicate_table;

四、聚合函数:统计数据的利器

聚合函数用于对数据进行统计计算,常用的有count(计数)、sum(求和)、avg(平均值)、max(最大值)、min(最小值)。

1. Count:计数

  • count(*):统计所有行数(包括 null)
  • count(字段):统计该字段非 null 的行数
  • count(distinct 字段):统计该字段去重后的行数
sql 复制代码
-- 统计学生总数
select count(*) from students;
-- 统计有QQ号的学生数
select count(qq) from students;
-- 统计数学成绩的去重数量
select count(distinct math) from exam_result;

2. Sum/Avg:求和 / 平均值

sql 复制代码
-- 统计数学成绩总分
select sum(math) from exam_result;
-- 统计平均总分
select avg(chinese + math + english) as 平均总分 from exam_result;

3. Max/Min:最大 / 最小值

sql 复制代码
-- 英语最高分
select max(english) from exam_result;
-- 70分以上的数学最低分
select min(math) from exam_result where math > 70;

五、分组查询:Group By + Having

group by用于按指定字段分组统计 ,常和聚合函数搭配;having用于对分组后的结果进行筛选(类似where,但where是分组前筛选)。

1. 基础分组统计

比如按部门统计平均工资和最高工资:

sql 复制代码
select deptno, avg(sal), max(sal) from emp group by deptno;

2. 多字段分组

按 "部门 + 岗位" 分组,统计每个部门每种岗位的平均工资和最低工资:

sql 复制代码
select deptno, job, avg(sal), min(sal) from emp group by deptno, job;

3. Having 筛选分组结果

筛选出 "平均工资低于 2000" 的部门:

sql 复制代码
select deptno, avg(sal) as myavg 
from emp 
group by deptno 
having myavg < 2000;

总结

今天讲的这些操作,是从 "单条数据操作" 到 "批量统计分析" 的进阶:

  • Update:灵活修改数据,支持基于原字段运算;
  • Delete/Truncate:删除数据的两种方式,注意自增主键和事务的区别;
  • 聚合函数:快速统计数据(计数、求和、平均等);
  • Group By+Having:分组统计并筛选结果。

MySQL 语法速查表

语法分类 核心关键字 / 语法结构 功能说明 示例代码(完整可执行) 注意事项
数据更新 - Update update 表名 set 列1=值1, 列2=值2... [where 条件] [order by ...] [limit ...]; 修改表中已有数据,支持单字段 / 多字段、条件更新、基于原数据更新 1. 单字段更新:update exam_result set math=80 where name='孙悟空';2. 多字段更新:update exam_result set math=60, chinese=70 where name='曹孟德';3. 基于原数据更新:update exam_result set math=math+30 order by chinese+math+english limit 3; 1. 无where条件会全表更新,风险极高;2. 不支持math+=30写法,需显式写math=math+30;3. 可搭配order bylimit实现精准批量更新
数据删除 - Delete delete from 表名 [where 条件] [order by ...] [limit ...]; 删除表中部分 / 全表数据,属于 DML 语句,支持事务回滚 1. 条件删除:delete from exam_result where name='孙悟空';2. 全表删除:delete from for_delete; 1. 全表删除后自增主键不重置;2. 执行速度较慢(逐行删除);3. 可通过事务回滚恢复数据
数据删除 - Truncate truncate table 表名; 截断表(删除全表数据),属于 DDL 语句,不可回滚 truncate table for_truncate; 1. 仅支持全表删除,无法加where条件;2. 自增主键重置为初始值;3. 执行速度快,不可回滚
插入查询结果 insert into 目标表 (列1,列2...) select 列1,列2... from 源表 [where 条件]; 将源表的查询结果直接插入目标表,常用于数据去重、批量迁移 1. 去重插入:insert into no_duplicate_table select distinct * from duplicate_table;2. 条件插入:insert into student_bak (id,name) select id,name from students where qq is not null; 1. 目标表需提前创建,列数和数据类型需与查询结果匹配;2. 可搭配distinct实现去重插入
聚合函数 - 计数 count(*) / count(字段) / count(distinct 字段) 统计数据行数,count(*)含 null,count(字段)不含 null,count(distinct 字段)去重统计 1. 统计总人数:select count(*) from students;2. 统计有 QQ 的人数:select count(qq) from students;3. 统计数学成绩去重数:select count(distinct math) from exam_result; count(1)count(*)功能一致,性能相近,推荐使用count(*)
聚合函数 - 求和 / 平均值 sum(字段) / avg(字段) sum计算字段总和,avg计算字段平均值(自动忽略 null 值) 1. 数学总分:select sum(math) from exam_result;2. 平均总分:select avg(chinese+math+english) as 平均总分 from exam_result; 1. 仅支持数值类型字段;2. avg(字段)等价于sum(字段)/count(字段)
聚合函数 - 最大 / 最小值 max(字段) / min(字段) max获取字段最大值,min获取字段最小值(支持数值 / 字符串 / 日期类型) 1. 英语最高分:select max(english) from exam_result;2. 70 分以上数学最低分:select min(math) from exam_result where math>70; 字符串类型按字符编码排序(如max('a') < max('b')
分组查询 - Group By select 分组字段, 聚合函数 from 表名 group by 分组字段1, 分组字段2...; 按指定字段分组,对每组数据进行聚合统计 1. 单字段分组:select deptno, avg(sal), max(sal) from emp group by deptno;2. 多字段分组:select deptno, job, avg(sal), min(sal) from emp group by deptno, job; 1. select后只能跟分组字段和聚合函数;2. 多字段分组时,先按第一个字段分组,再按第二个字段细分
分组筛选 - Having select 分组字段, 聚合函数 from 表名 group by 分组字段 having 筛选条件; 对分组后的结果进行筛选(分组后筛选,支持聚合函数别名) select deptno, avg(sal) as myavg from emp group by deptno having myavg < 2000; 1. where用于分组前筛选,having用于分组后筛选;2. having支持聚合函数别名,where不支持

注意

语法优先级:where(分组前)> group by(分组)> having(分组后)> order by(排序)> limit(分页);

相关推荐
阿巴斯甜19 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker19 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952720 小时前
Andorid Google 登录接入文档
android
黄林晴21 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android