MySQL 进阶:聚集函数、分组、约束、多表查询

本文承接 MySQL 基础篇,继续讲解聚集函数、分组查询、HAVING、密码修改、备份恢复、单表 / 多表约束、表关系设计、多表查询(内连接 / 外连接 / 子查询)

一、聚集函数(常用统计)

MySQL 提供 5 种常用聚集函数,用于对查询结果做统计计算。

  1. count():统计记录数
  2. sum():求和
  3. avg():求平均值
  4. max():求最大值
  5. min():求最小值

常用练习

复制代码
-- 数学平均分(null转0)
select avg(ifnull(math,0)) from stu;

-- 班级总分平均分
select avg(ifnull(math,0)+english+chinese) from stu;

-- 英语最高分、最低分
select max(english), min(english) from stu;

二、分组查询(GROUP BY 重要)

使用 group by 字段 对数据进行分组,常与聚集函数一起使用。

1. 建表测试

复制代码
create database day16;
use day16;

create table orders(
    id int,
    product varchar(20),
    price float
);

insert into orders(id,product,price) values(1,'电视',900);
insert into orders(id,product,price) values(2,'洗衣机',100);
insert into orders(id,product,price) values(3,'洗衣粉',90);
insert into orders(id,product,price) values(4,'电视',900);
insert into orders(id,product,price) values(5,'洗衣粉',90);
insert into orders(id,product,price) values(6,'洗衣粉',90);

2. 分组查询练习

复制代码
-- 按商品分组,统计每类总价与数量
select product,sum(price),count(*) from orders group by product;

-- 分组后过滤:总价>100的商品
select product from orders group by product having sum(price) > 100;

3. WHERE 与 HAVING 区别

  • where :分组前过滤,不能使用聚集函数
  • having :分组后过滤,可以使用聚集函数,通常跟在 group by 后

4. 查询语句固定顺序

复制代码
select ... from ... where ... group by ... having ... order by ...

没有对应条件时,直接去掉关键字即可。


三、MySQL 修改密码

步骤

  1. 停止 MySQL 服务:services.msc

  2. 跳过权限认证启动:

    mysqld --skip-grant-tables

  3. 新 CMD 直接登录:mysql -u root -p(无需密码)

  4. 切换数据库:use mysql;

  5. 修改密码:

    update user set authentication_string=password('root') WHERE user='root';

  6. 关闭两个 CMD,任务管理器结束 mysqld 进程

  7. 重启 MySQL 服务


四、数据库备份与恢复

1. 备份(命令行执行,非登录状态)

复制代码
mysqldump -u 用户名 -p 数据库名 > 文件名.sql

回车后输入密码。

2. 恢复(先建空库并 use)

复制代码
mysql -u 用户名 -p 数据库名 < 文件名.sql

注意事项

  • 不在 MySQL 登录状态执行
  • 命令末尾没有分号
  • 注意 >< 方向
  • 恢复用 mysql,备份用 mysqldump

五、单表约束

1. 主键约束(PRIMARY KEY 重点)

  • 唯一标识一条记录
  • 特点:唯一、非空、可被外键引用
创建主键两种方式
复制代码
-- 方式1
create table person(
    id int primary key,
    name varchar(30)
);

-- 方式2
create table person(
    id int,
    name varchar(30),
    primary key (id)
);

2. 主键自增长(AUTO_INCREMENT)

数据库自动维护主键值,插入填 null 即可。

复制代码
create table person(
    id int primary key auto_increment,
    name varchar(30)
);

insert into person values (null,'聪聪');
insert into person values (null,'美美');
insert into person values (null,'小凤');

3. 唯一约束 & 非空约束

  • unique:值唯一,可空
  • not null:值不能为空

六、多表外键约束

1. 场景:部门 & 员工

  • 一个部门多个员工,一个员工属于一个部门
  • 不加外键可随意删除部门,业务不合理

2. 建表

复制代码
-- 部门表(一方)
create table dept(
    did int primary key auto_increment,
    dname varchar(30)
);

-- 员工表(多方)
create table emp(
    eid int primary key auto_increment,
    ename varchar(30),
    sal double,
    dno int
);

3. 添加外键

复制代码
-- 创建表时指定
create table emp(
    eid int primary key auto_increment,
    ename varchar(30),
    sal double,
    dno int,
    foreign key (dno) references dept (did)
);

-- 已存在表添加外键
alter table emp add foreign key (dno) references dept (did);

添加外键后,无法删除被引用的部门,保证数据完整性。


七、表关系设计

1. 一对多

  • 例:部门 ↔ 员工、分类 ↔ 商品
  • 原则:在多方表添加外键,指向一方主键

2. 多对多

  • 例:学生 ↔ 课程、用户 ↔ 角色
  • 原则:创建中间表,包含两个外键分别指向两张表主键,拆成两个一对多

3. 一对一(了解)

  • 例:用户 ↔ 用户详情
  • 原则:任意一方添加唯一外键指向另一方主键

4. 购物网站表关系

  • 用户 → 订单(一对多)
  • 订单 ↔ 商品(多对多,中间表:订单商品)
  • 分类 → 商品(一对多)

八、多表查询(重要)

1. 笛卡尔积

无条件关联两表,结果是行数乘积(业务几乎不用)

复制代码
select * from dept,emp;

2. 内连接(只查关联数据)

(1)显式内连接
复制代码
select * from dept inner join emp on dept.did = emp.dno;
(2)隐式内连接(最常用)
复制代码
select d.dname,e.ename,e.sal
from dept d,emp e
where d.did = e.dno;

3. 外连接(保留某表全部数据)

(1)左外连接

左表为准,显示左表所有数据,匹配右表数据

复制代码
select * from dept left outer join emp on dept.did = emp.dno;
(2)右外连接

右表为准,显示右表所有数据,匹配左表数据

复制代码
select * from dept right outer join emp on dept.did = emp.dno;

4. 多表查询总结

  • 内连接:只查匹配数据
  • 左连接:左表全出,匹配右表
  • 右连接:右表全出,匹配左表

九、子查询

一个查询中嵌套另一个查询,先执行子查询,再用结果做外层条件。

示例:查询英语成绩 > 平均分的学生

复制代码
select * from stu where english > (select avg(english) from stu);

子查询常用运算符

  • > < >= <= = <>
  • any:满足任意一个
  • all:满足所有

十、多表查询综合实战

1. 查询聪聪的部门与姓名

复制代码
select d.dname,e.ename
from dept d,emp e
where d.did = e.dno and e.ename = '聪聪';

2. 统计每个部门人数

复制代码
select d.dname,count(*)
from dept d,emp e
where d.did = e.dno
group by d.dname;

3. 统计各部门平均工资

复制代码
select d.dname,avg(e.sal)
from dept d,emp e
where d.did = e.dno
group by d.dname;

4. 平均工资 > 公司总平均的部门

复制代码
select d.dname,avg(e.sal)
from dept d,emp e
where d.did = e.dno
group by d.dname
having avg(e.sal) > (select avg(sal) from emp);

总结

  1. 聚集函数:count/sum/avg/max/min
  2. 分组:group by + having
  3. 密码修改、备份恢复
  4. 主键、自增、唯一、非空、外键约束
  5. 一对多、多对多、一对一表设计
  6. 内连接、左 / 右外连接、子查询
  7. 多表查询实战案例
相关推荐
bzmK1DTbd2 小时前
Git版本控制:Java项目中的分支管理与合并策略
java·开发语言·git
Rust研习社3 小时前
为什么 Rust 没有空指针?
开发语言·后端·rust
kyriewen113 小时前
WebAssembly:前端界的“外挂”,让C++代码在浏览器里跑起来
开发语言·前端·javascript·c++·单元测试·ecmascript
S1998_1997111609•X4 小时前
论当今社会主义与人文关怀人格思想下的恶意仿生注入污染蜜罐描述进行函数值非法侵入爬虫的咼忄乂癿〇仺⺋.
数据库·网络协议·百度·ssh·开闭原则
其实防守也摸鱼5 小时前
CTF密码学综合教学指南--第九章
开发语言·网络·python·安全·网络安全·密码学·ctf
砚底藏山河5 小时前
Python量化开发:2026最佳实时股票数据API接口推荐与对比
开发语言·windows·python
倔强的石头_5 小时前
kingbase备份与恢复实战(六)—— 备份自动化与保留策略:Windows任务计划+日志追溯
数据库
AlunYegeer6 小时前
JAVA,以后端的视角理解前端。在全栈的路上迈出第一步。
java·开发语言·前端
轻刀快马6 小时前
别被 ORM 框架宠坏了:从一场“订单消失”悬案,看懂 MySQL 为什么要强推 InnoDB
数据库·mysql
hixiong1236 小时前
C# OpenvinoSharp使用DINOv2模型进行图像相似度计算
开发语言·c#