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. 多表查询实战案例
相关推荐
xqqxqxxq17 分钟前
MySQL 数据类型笔记
数据库·笔记·mysql
techdashen20 分钟前
Go设计取舍之四: map不变时能否并发修改不同value
开发语言·后端·golang
小小小米粒28 分钟前
阿姆达尔定律(Amdahl‘s Law)
java·开发语言
知彼解己28 分钟前
Java 版本演进
java·开发语言·spring boot
风样滴男人哟33 分钟前
PHP特性之反射类ReflectionClass机制
android·开发语言·php
Logintern0940 分钟前
理解MySQL数据库的“事务与锁”
数据库·mysql
看昭奚恤哭1 小时前
Flutter 布局核心思想
开发语言·javascript·flutter
朱容zr3331331 小时前
为什么推荐使用自增主键?使用UUID作为主键的优缺点是什么?
java·运维·数据库·后端·mysql·面试·性能优化
麻瓜code1 小时前
【Redis 】数据类型、持久化与过期删除
数据库·redis·缓存
空杆推不起1 小时前
穿透 Flink CDC 表层用法:数据库日志捕获机制、Flink Source 运行时、端到端一致性底层原理详解
大数据·数据库·flink