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. 多表查询实战案例
相关推荐
hef2889 小时前
如何生成特定SQL的AWR报告_@awrsqrpt.sql深度剖析单条语句性能
jvm·数据库·python
以神为界10 小时前
Python入门实操:基础语法+爬虫入门+模块使用全指南
开发语言·网络·爬虫·python·安全·web
xcjbqd010 小时前
Python API怎么加Token认证_JWT生成与验证拦截器实现
jvm·数据库·python
二月十六10 小时前
SQL Server 2022 新语法:IS [NOT] DISTINCT FROM 彻底解决 NULL 比较难题
数据库·sqlserver
~ rainbow~10 小时前
前端转型全栈(四)——常见的错误及解决方案
数据库·oracle·全栈
数厘11 小时前
2.1SQL 学习:先懂数据库概念再学 SQL
数据库·sql·学习
逻辑驱动的ken11 小时前
Java高频面试题:03
java·开发语言·面试·求职招聘·春招
Cat_Rocky11 小时前
redis哨兵模式
数据库·redis
噜噜大王_11 小时前
深入理解 C 语言内存操作函数:memcpy、memmove、memset、memcmp
c语言·开发语言