在前三篇中,我们拆解了 DQL 的基础查询、条件 / 分组查询、排序 / 分页查询,今天要讲两个核心内容:DQL 语句的执行顺序 (面试必问)和 DQL 综合实战案例 ,最后引出 MySQL 的权限控制语言 DCL,完成 DQL 系列的收尾。所有案例仍基于 sicheng 数据库的 student 表。
目录
[一、DQL 执行顺序:编写顺序≠执行顺序](#一、DQL 执行顺序:编写顺序≠执行顺序)
[1. 编写顺序 vs 执行顺序对比](#1. 编写顺序 vs 执行顺序对比)
[2. 执行顺序验证(核心实验)](#2. 执行顺序验证(核心实验))
[实验 1:FROM 先于 WHERE 执行](#实验 1:FROM 先于 WHERE 执行)
[实验 2:WHERE 先于 SELECT 执行](#实验 2:WHERE 先于 SELECT 执行)
[实验 3:SELECT 先于 ORDER BY 执行](#实验 3:SELECT 先于 ORDER BY 执行)
[3. 执行顺序总结(记忆口诀)](#3. 执行顺序总结(记忆口诀))
[二、DQL 综合实战:多语法组合(业务场景)](#二、DQL 综合实战:多语法组合(业务场景))
[案例 1:统计各班级的女生人数(条件 + 分组)](#案例 1:统计各班级的女生人数(条件 + 分组))
[案例 2:分页展示成绩优异的学生(条件 + 排序 + 分页)](#案例 2:分页展示成绩优异的学生(条件 + 排序 + 分页))
[案例 3:多条件组合查询(模糊 + 范围 + 排序)](#案例 3:多条件组合查询(模糊 + 范围 + 排序))
[三、DQL 全知识点总结(核心回顾)](#三、DQL 全知识点总结(核心回顾))
[四、预告:DCL 数据控制语言](#四、预告:DCL 数据控制语言)
[五、最后:DQL 学习建议](#五、最后:DQL 学习建议)
一、DQL 执行顺序:编写顺序≠执行顺序
这是 DQL 中最容易混淆的知识点:我们编写 SQL 的顺序和 MySQL 实际执行的顺序完全不同,理解这一点能避免很多语法错误。
1. 编写顺序 vs 执行顺序对比
| 编写顺序(我们写的) | 执行顺序(MySQL 实际执行) | 说明 |
|---|---|---|
| 1. select 字段列表 | 5. select 字段列表 | 最后才选择要返回的字段 |
| 2. from 表名 | 1. from 表名 | 先确定查询的数据源(表) |
| 3. where 条件 | 2. where 条件 | 过滤原始记录 |
| 4. group by 分组字段 | 3. group by 分组字段 | 对过滤后的记录分组 |
| 5. having 分组后条件 | 4. having 分组后条件 | 过滤分组后的结果 |
| 6. order by 排序字段 | 6. order by 排序字段 | 对最终结果排序 |
| 7. limit 分页参数 | 7. limit 分页参数 | 最后分页处理 |
2. 执行顺序验证(核心实验)
通过 "别名是否生效" 可以直观验证执行顺序,这是面试高频考点。
实验 1:FROM 先于 WHERE 执行
给表 student 起别名 s,在 where 中使用 s.age,执行成功:
sql
select name, age
from student s -- FROM先执行,给表起别名s
where s.age > 16; -- WHERE可以使用表别名s
结论:from 最先执行,确定数据源后,where 才能使用表别名。
实验 2:WHERE 先于 SELECT 执行
在 select 中给 age 起别名 stu_age,在 where 中使用 stu_age,会报错:
sql
-- 错误写法(WHERE中使用SELECT的别名)
select name, age as stu_age
from student
where stu_age > 16; -- 报错:Unknown column 'stu_age' in 'where clause'
-- 正确写法(WHERE中用原字段名)
select name, age as stu_age
from student
where age > 16;
结论:where 执行时,select 还未执行,因此无法识别 select 中定义的字段别名。
实验 3:SELECT 先于 ORDER BY 执行
在 select 中给 score 起别名 stu_score,在 order by 中使用该别名,执行成功:
sql
select name, score as stu_score
from student
order by stu_score desc; -- ORDER BY可以使用SELECT的别名
结论:order by 在 select 之后执行,因此能识别字段别名。
3. 执行顺序总结(记忆口诀)
"查表 → 过滤 → 分组 → 筛选 → 选字段 → 排序 → 分页":
- FROM:定位要查询的表;
- WHERE:过滤掉不符合条件的原始记录;
- GROUP BY:按指定字段分组;
- HAVING:过滤分组后的结果;
- SELECT:选择要返回的字段;
- ORDER BY:对结果按指定规则排序;
- LIMIT:分页展示最终结果。
二、DQL 综合实战:多语法组合(业务场景)
结合前几篇的知识点,完成 3 个典型的业务查询案例,覆盖 DQL 全核心语法。
案例 1:统计各班级的女生人数(条件 + 分组)
需求:统计每个班级中年龄大于 16 岁的女生人数,只显示人数大于 1 的班级。
sql
select class 班级, count(*) 女生人数
from student
where gender = '女' and age > 16 -- 分组前过滤:女生且年龄>16
group by class -- 按班级分组
having count(*) > 1; -- 分组后过滤:人数>1
执行分析:
- FROM:定位
student表; - WHERE:筛选出 "女且年龄> 16" 的学生(孙七、吴九);
- GROUP BY:按班级分组(孙七:高一 (1) 班;吴九:高一 (3) 班);
- HAVING:过滤出人数 > 1 的班级(无符合条件的,结果为空);
- SELECT:返回班级和女生人数;
- 无 ORDER BY 和 LIMIT,直接返回结果。
案例 2:分页展示成绩优异的学生(条件 + 排序 + 分页)
需求:查询成绩大于 85 分的学生,按成绩降序排列,分页显示第 2 页(每页 2 条)。
sql
select name 姓名, class 班级, score 成绩
from student
where score > 85 -- 条件过滤:成绩>85
order by score desc -- 按成绩降序
limit 2, 2; -- 分页:第2页,每页2条(起始索引=(2-1)×2=2)
执行结果:
- 赵六(高一 (2) 班,88.0 分);
- 吴九(高一 (3) 班,89.5 分)。
案例 3:多条件组合查询(模糊 + 范围 + 排序)
需求:查询姓名为两个字、年龄在 16~18 岁之间的男生,按年龄升序、成绩降序排列。
sql
select
name 姓名,
age 年龄,
score 成绩
from student
where
name like '__' -- 姓名两个字
and age between 16 and 18 -- 年龄16~18
and gender = '男' -- 男生
order by
age asc, -- 年龄升序
score desc; -- 成绩降序
执行结果:16 岁:张三(85.5)→周八(76.0);17 岁:李四(92.0)→郑十(81.0);18 岁:赵六(88.0)→孙十二(79.0)。
三、DQL 全知识点总结(核心回顾)
| 模块 | 核心语法 | 关键要点 |
|---|---|---|
| 基础查询 | select 字段 from 表名 |
显式列字段优于 *;distinct 去重;as 设别名 |
| 条件查询 | where 条件 |
掌握比较 / 逻辑 / 特殊运算符;between and 是闭区间;like 通配符 |
| 聚合函数 | count/max/min/avg/sum |
纵向计算,null 值不参与;count(*) 统计总记录数 |
| 分组查询 | group by 字段 having 条件 |
where 分组前过滤,having 分组后过滤;having 可使用聚合函数 |
| 排序查询 | order by 字段 排序方式 |
多字段排序按优先级;降序需写 desc,升序省略 asc |
| 分页查询 | limit 起始索引, 记录数 |
起始索引 =(页码 - 1)× 每页条数;limit 放最后 |
| 执行顺序 | FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY→LIMIT | where 不能用 SELECT 别名,order by 可以 |
四、预告:DCL 数据控制语言
至此,我们已经掌握了 MySQL 的三大核心语言:
- DDL:操作数据库 / 表结构;
- DML:操作表中数据(增删改);
- DQL:查询表中数据(核心)。
接下来要学习的 DCL(Data Control Language,数据控制语言),是管理 MySQL 权限的核心工具,比如:
- 用户管理 :创建 / 删除数据库用户(如创建
stu_user用户,仅能访问sicheng数据库); - 权限控制 :授予 / 撤销用户权限(如给
stu_user授予student表的查询权限,禁止修改权限); - 权限回收 :撤销用户的不当权限(如收回
stu_user的删除权限)。
DCL 是数据库管理员(DBA)的常用技能,也是后端开发的进阶知识点 ------ 比如项目中需要创建只读用户供应用程序访问数据库,避免使用 root 用户导致权限过大。关注我,下一篇带你吃透 DCL 核心语法!
五、最后:DQL 学习建议
- 多练 :基于
student表自己设计查询需求(如 "统计各班级的平均年龄""查询成绩倒数 3 名的学生"),手写 SQL 验证; - 记顺序:执行顺序是面试高频考点,结合别名实验记忆;
- 避坑 :
where不用聚合函数、limit放最后、between and顺序不反。
DQL 是 MySQL 中最核心的内容,掌握好它,就能应对 80% 以上的业务开发需求。下一篇我们进入 DCL 权限控制的学习,见!
希望这篇文章对你有帮助,如果你有任何问题或建议,欢迎在评论区留言。谢谢阅读(求攒攒 收藏 关注)!
