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(分页);

相关推荐
苹果醋32 小时前
JAVA设计模式之策略模式
java·运维·spring boot·mysql·nginx
查克陈Chuck2 小时前
Launcher3模块化-组件化
android·launcher开发
千里马学框架2 小时前
google官方文档:深入剖析ProtoLog原理及Winscope的查看方式
android·车载系统·framework·perfetto·系统开发·winscope
apihz2 小时前
获取当前北京时间的免费API接口教程
android
Dovis(誓平步青云)2 小时前
《MySQL从入门:基础安装与数据库核心概念全解析》
数据库·mysql
apihz2 小时前
货币汇率换算免费API接口(每日更新汇率)
android·java·开发语言
恋猫de小郭2 小时前
八年开源,GSY 用五种技术开发了同一个 Github 客户端,这次轮到 AI + Compose
android·前端·flutter
sc.溯琛11 小时前
MySQL 高级实战:触发器、事务与数据库备份恢复全攻略
android·adb
zhuzewennamoamtf11 小时前
Linux SPI设备驱动
android·linux·运维