前言
在关系型数据库(MySQL 为主)开发工作里,DQL(Data Query Language,数据查询语言)是 SQL 使用频次最高的语法子集,核心关键字为SELECT,业务数据筛选、报表统计、前端接口数据读取全都依赖 DQL 完成。本文顺着课程章节:基础查询、条件查询、聚合函数、分组查询、排序查询、分页查询、实战案例、SQL 执行顺序、知识点总结,系统拆解 DQL 用法,附带可直接复刻的 SQL 示例、易错避坑点,适配后端入门学习者做技术博客沉淀、面试复习。
一、15 节:DQL 基础查询(SELECT 基础语法)
1. 标准基础语法格式
-- 查询指定单列/多列
SELECT 列名1,列名2 FROM 表名;
-- 查询整张表所有字段(生产环境禁止滥用*,会触发不必要的全字段IO)
SELECT * FROM 表名;
-- 字段起别名,AS关键字可省略
SELECT 字段 AS 别名, 字段2 别名2 FROM 表名;
-- 去重查询DISTINCT
SELECT DISTINCT 字段 FROM 表名;
-- 字段做运算(数值列支持加减乘除)
SELECT 字段+10 FROM 表名;
2. 实操样例(以员工表 emp 为例)
-- 1.查询员工姓名、薪资两列
SELECT name,salary FROM emp;
-- 2.给薪资列起别名month_salary
SELECT name,salary AS month_salary FROM emp;
-- 3.去重查询员工所属部门编号
SELECT DISTINCT dept_id FROM emp;
-- 4.计算员工年薪(月薪*12)
SELECT name,salary*12 annual_salary FROM emp;
3. 避坑提醒
-
SELECT *在大表场景性能很差,索引无法精准命中,线上业务务必枚举需要的字段; -
DISTINCT 对多列生效时,会按照多列组合值整体去重,不是单独针对首个字段;
-
NULL 参与算术运算,运算结果永远为 NULL,不能直接靠加减处理空薪资字段。
二、16 节:DQL 条件查询(WHERE 子句过滤行数据)
1. 语法结构
SELECT 字段列表 FROM 表名 WHERE 筛选条件;
WHERE 执行时机:FROM 加载数据表数据后,逐行校验条件,只把符合规则的行向下传递给后续逻辑。
2. 常用条件运算符分类
-
基础比较运算符:
>、<、>=、<=、=、!= / <>(两个写法都代表不等于) -
范围匹配:
BETWEEN 最小值 AND 最大值(闭区间,包含两端边界)、IN(值1,值2)匹配离散枚举值 -
空值判定:
IS NULL、IS NOT NULL(禁止用=NULL做空值匹配,SQL 中 NULL 不等于自身) -
模糊匹配
LIKE:%匹配任意长度任意字符、_匹配单个任意字符 -
逻辑运算符:
AND(且)、OR(或)、NOT(取反),优先级:AND > OR
3. 代码示例
-- 1.查询薪资大于8000的员工
SELECT name,salary FROM emp WHERE salary>8000;
-- 2.薪资区间5000~10000的员工(两种等价写法)
SELECT name FROM emp WHERE salary BETWEEN 5000 AND 10000;
SELECT name FROM emp WHERE salary>=5000 AND salary<=10000;
-- 3.部门编号为1、3的员工
SELECT name FROM emp WHERE dept_id IN(1,3);
-- 4.查询姓名姓张的员工模糊匹配
SELECT name FROM emp WHERE name LIKE '张%';
-- 5.查询薪资不为空的员工
SELECT name FROM emp WHERE salary IS NOT NULL;
易错点
OR 和 AND 混用不加括号会出现逻辑偏差,例:想筛选「薪资 > 10000 或者 部门 id=2 且薪资 > 6000」,必须书写salary>10000 OR (dept_id=2 AND salary>6000)。
三、17 节:DQL 聚合函数(纵向整列做统计计算)
1. 核心概念
普通 WHERE 做横向单行数据筛选 ,聚合函数对指定列做纵向全行汇总统计,MySQL 内置通用聚合函数:
|---------------|--------|-----------------------------------------|
| 函数 | 功能说明 | NULL 处理规则 |
| COUNT (列 /*) | 统计数据行数 | COUNT (*) 统计所有行;COUNT (字段) 自动跳过 NULL 行 |
| SUM (列) | 列的数值求和 | 忽略 NULL |
| AVG (列) | 列平均值 | 忽略 NULL |
| MAX (列) | 取列最大值 | 忽略 NULL |
| MIN (列) | 取列最小值 | 忽略 NULL |
2. 示例 SQL
-- 员工总人数
SELECT COUNT(*) total_emp FROM emp;
-- 全体员工薪资总和、平均薪资
SELECT SUM(salary) sum_sal,AVG(salary) avg_sal FROM emp;
-- 最高、最低月薪
SELECT MAX(salary) max_sal,MIN(salary) min_sal FROM emp;
关键避坑
AVG 函数跳过 NULL 行,若岗位空缺薪资为 NULL,空缺记录不会纳入平均值分母统计,业务要补默认值再做统计;WHERE 子句内不能直接书写聚合函数,聚合过滤要放到 HAVING 子句。
四、18 节:DQL 分组查询(GROUP BY 分组 + having 分组后过滤)
1. 标准语法
SELECT 分组字段,聚合函数 FROM 表名
WHERE 分组前置行过滤
GROUP BY 分组字段
HAVING 分组结果二次过滤;
WHERE:分组前筛选原始单行数据,不能引用聚合函数;HAVING:分组完成后对每组统计结果过滤,支持书写聚合函数。
2. 实操案例:按部门分组统计部门平均薪资,筛选部门平均薪资大于 7000 的分组
SELECT dept_id,AVG(salary) dept_avg_sal
FROM emp
WHERE salary>3000 -- 先剔除底薪过低无效数据,减少分组计算量
GROUP BY dept_id
HAVING AVG(salary) > 7000;
硬性规范(MySQL 开发强制约束)
SELECT 后非聚合的普通字段,必须出现在 GROUP BY 分组字段列表内,禁止查询分组外零散字段(MySQL 宽松模式会产出逻辑错乱数据)。
五、19 节:DQL 排序查询(ORDER BY 对结果集排序)
1. 语法规则
SELECT 字段 FROM 表名 [WHERE过滤] [GROUP BY分组]
ORDER BY 排序字段1 排序方式,排序字段2 排序方式;
排序标识:ASC升序(默认可省略)、DESC降序;支持多字段排序:优先按首个字段排序,首个字段数值相同时,启用第二个字段补充排序。
示例 SQL
-- 员工薪资降序排列
SELECT name,salary FROM emp ORDER BY salary DESC;
-- 部门编号升序,同部门内薪资由高到低排序
SELECT dept_id,name,salary FROM emp ORDER BY dept_id ASC,salary DESC;
补充特性
NULL 值在升序排序场景,MySQL 会把 NULL 行排在结果集最顶部;排序字段建议建立索引,大数据量表排序避免触发 filesort 文件磁盘排序拖垮性能。
六、20 节:DQL 分页查询(LIMIT 实现数据分页)
1.MySQL 专属分页语法
SELECT 字段 FROM 表名 前置过滤逻辑 ORDER BY 排序列
LIMIT 起始偏移量offset,单页展示条数page_size;
分页计算公式:offset = (页码-1)*每页条数;LIMIT 仅 MySQL、MariaDB 支持,Oracle 使用 ROWNUM、SQL Server 使用 OFFSET FETCH 做分页。
业务示例:每页 10 条,查询第 3 页数据
-- offset=(3-1)*10=20
SELECT * FROM emp ORDER BY emp_id LIMIT 20,10;
-- MySQL8.0可读更强的写法
SELECT * FROM emp ORDER BY emp_id LIMIT 10 OFFSET 20;
性能优化要点
深分页(offset 数值上万)性能会急剧衰减,优化方案:主键索引分页、子查询先定位主键再回表查询;分页必须搭配稳定排序字段(主键 ID),避免分页出现数据重复、漏取。
七、21 节:DQL 综合案例练习(整合多类子句)
业务需求背景
员工表 emp 字段:emp_id (主键),name,salary,dept_id,entry_date 入职时间,完成 3 个综合需求:
-
统计 2024 年入职员工,分部门统计部门员工人数,只保留部门人数≥2 的分组;按人数降序分页,取前 5 条结果
SELECT dept_id,COUNT(emp_id) emp_cnt
FROM emp
WHERE entry_date >= '2024-01-01' AND entry_date < '2025-01-01'
GROUP BY dept_id
HAVING COUNT(emp_id)>=2
ORDER BY emp_cnt DESC
LIMIT 5; -
模糊筛选姓名带 "李" 字、月薪 6k~15k 的员工,薪资倒序展示
SELECT name,salary FROM emp
WHERE name LIKE '%李%' AND salary BETWEEN 6000 AND 15000
ORDER BY salary DESC; -
排查部门内最高薪资低于 5000 的低效部门编号
SELECT dept_id,MAX(salary) max_sal
FROM emp
GROUP BY dept_id
HAVING MAX(salary)<5000;
八、22 节:SELECT 语句底层真实执行顺序(高频面试考点)
1. 开发者书写 SQL 的人为书写顺序
SELECT → DISTINCT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
2.MySQL 引擎真实物理执行顺序(决定别名引用、子句可用范围)
-
FROM:加载数据表、执行关联表连接,拿到原始数据源
-
WHERE:逐行做行级过滤,淘汰不符合条件的数据行
-
GROUP BY:按指定字段拆分数据分组,初始化每组聚合统计上下文
-
HAVING:基于分组完成后的聚合结果,做分组级过滤(唯一能校验聚合结果的阶段)
-
SELECT:计算字段表达式、给字段赋予别名、执行 DISTINCT 全局去重
-
ORDER BY:对最终投影后的结果集做全局排序
-
LIMIT:截断结果集,输出分页限定条数的数据
顺序衍生 3 条必懂规则
-
WHERE 阶段早于 SELECT,WHERE 子句无法引用 SELECT 内自定义别名;HAVING 在分组阶段后,可引用分组内聚合计算结果;
-
GROUP BY 前置过滤优先用 WHERE,能提前裁剪数据量,减少分组磁盘内存开销,不要把行级筛选全堆进 HAVING;
-
ORDER BY 可以复用 SELECT 定义的字段别名,排序阶段在 SELECT 字段投影之后。
九、23 节:DQL 全章节知识点复盘总结
1. 子句职能 & 使用优先级总览
-
FROM:数据源入口,所有查询逻辑的起始基准;
-
WHERE(行前置过滤):过滤原始单行数据,不可写聚合函数,做早期数据裁剪优化性能;
-
GROUP BY:拆分数据分组,适配部门、品类类批量统计需求;
-
HAVING(分组后置过滤):校验聚合统计结果,解决 WHERE 无法筛选聚合值的局限;
-
SELECT:决定最终对外暴露哪些字段,做字段别名、列运算、DISTINCT 去重;
-
ORDER BY:统一规范结果排序规则,支撑列表顺序展示;
-
LIMIT:做分页数据截断,适配前端分页列表交互场景。
2. 高频易错问题汇总
-
NULL 匹配错误:不用
=NULL,统一用IS NULL / IS NOT NULL;NULL 参与四则运算结果固定为 NULL; -
WHERE/HAVING 选型混淆:单行原始数据过滤选 WHERE;分组聚合后的统计值过滤必须选 HAVING;
-
GROUP BY 字段不匹配:SELECT 非聚合字段必须归入 GROUP BY 分组字段,规避非确定性数据;
-
分页深分页性能劣化:大 offset 场景改用主键游标分页;排序固定依托主键保证分页数据不错乱;
-
模糊查询全通配前缀
%xxx会使索引失效,百万级数据表禁止大范围前缀模糊检索。
3. 生产环境性能优化通用建议
-
杜绝线上业务
SELECT *,按需枚举查询字段,降低网络传输与磁盘 IO 开销; -
WHERE、GROUP BY、ORDER BY、分页排序的高频字段提前创建适配索引,降低全表扫描概率;
-
能前置在 WHERE 做的数据过滤,绝不延后到 HAVING 做筛选,压缩分组阶段处理的数据体量;
-
超大数据量分页场景,放弃传统 offset 分页,改用「主键游标分页」(WHERE id > 上一页最后主键 LIMIT page_size),大幅降低数据库扫描行数。
结语
DQL 是数据库开发、后端接口开发、数据报表开发的核心基础,不只要掌握语法拼写,还要吃透底层执行顺序,区分 WHERE/HAVING、聚合函数、分组查询的适用边界,规避线上慢查询、分页错乱、分组数据异常等典型线上故障。后续进阶可拓展联表 JOIN 查询、子查询、窗口函数,完成复杂多表关联统计、排行类业务需求。
文档导出指引
你可以复制全文内容:
-
Word 文档:新建空白 Word,粘贴全文,按标题层级设置「一级标题(章节大标题)、二级标题(小节标题)、正文、代码块( Courier New 字体)」排版后直接保存
.docx; -
Markdown 文档:新建后缀为
.md文件,直接粘贴文本,可上传掘金、CSDN、个人博客站点发布; -
PDF 格式:Word 排版完成后,执行「另存为→导出为 PDF」即可生成 PDF 归档文档。
要不要我补充适配 CSDN 站点的标签、SEO 标题和段落配图建议,直接帮你完善成可一键发布的博客成品?