SQL 是测试、后端、数分岗位校招面试的必考内容,很多同学背了语法,一到面试就容易混淆执行顺序、JOIN
类型、索引和事务隔离级别这些高频考点。本文以 MySQL
为主,整理面试最常问到的核心知识点,剔除冷门复杂内容,做成速查清单。适合考前快速复盘、刷题时对照查阅,帮你把高频考点牢牢掌握
一、SQL 四大分类
| 分类 | 全称 | 作用 | 常见语句 |
|---|---|---|---|
| DDL | 数据定义 | 定义表结构 | CREATE、ALTER、DROP、TRUNCATE |
| DML | 数据操作 | 增删改数据 | INSERT、UPDATE、DELETE |
| DQL | 数据查询 | 查数据 | SELECT |
| DCL | 数据控制 | 权限控制 | GRANT、REVOKE |
▎ 易混:DELETE 是 DML,可回滚;TRUNCATE 是 DDL,清空表且不能回滚。
二、SQL 语句执行顺序(高频考点)
书写顺序:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
实际执行顺序:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
这解释了两个常见现象:
- WHERE 里不能用 SELECT 起的别名(因为 WHERE 先执行)
- ORDER BY 可以用别名(因为 SELECT 在它之前执行)
三、常用查询语法
SELECT列1,列2FROM表WHERE条件GROUPBY列HAVING组条件ORDERBY列[ASC|DESC]LIMIT偏移量,条数;四、JOIN 全解析
| 类型 | 结果 | 记忆方式 |
|---|---|---|
| INNER JOIN | 两表都匹配上的行 | 交集 |
| LEFT JOIN | 左表全部 + 右表匹配(无匹配为 NULL) | 左表保底 |
| RIGHT JOIN | 右表全部 + 左表匹配 | 右表保底 |
| FULL JOIN | 两表全部(MySQL 不直接支持,用 UNION 模拟) | 并集 |
| CROSS JOIN | 笛卡尔积 | 全组合 |
口诀:INNER 取交集,LEFT 左表全,RIGHT 右表全。
五、聚合函数与 GROUP BY
- 常用聚合:COUNT()、SUM()、AVG()、MAX()、MIN()
- GROUP BY:按某列分组统计
WHERE 与 HAVING 的区别:
| 对比 | WHERE | HAVING |
|---|---|---|
| 过滤对象 | 行 | 分组后的组 |
| 能否用聚合函数 | 不能 | 能 |
| 执行时机 | 分组前 | 分组后 |
SELECTdept,COUNT(*)AScntFROMemployeeWHEREsalary>5000GROUPBYdeptHAVINGCOUNT(*)>3;六、NULL 的坑(面试爱考)
- 判断 NULL 必须用 IS NULL / IS NOT NULL,= NULL 永远不成立
- COUNT(*) 统计所有行;COUNT(列) 不统计该列为 NULL 的行
- NULL 参与算术运算结果是 NULL
- NULL 与任何值比较结果为 UNKNOWN,不会走索引
七、子查询
| 类型 | 返回 | 示例场景 |
|---|---|---|
| 标量子查询 | 单个值 | WHERE salary > (SELECT AVG(salary) FROM emp) |
| 列子查询 | 一列多行 | WHERE id IN (SELECT id FROM …) |
| 表子查询 | 多行多列 | FROM (SELECT …) AS t |
IN vs EXISTS:一般子查询结果集大用 EXISTS,小用 IN;NOT IN 遇到 NULL 会返回空结果,这是经典坑。
八、索引知识点
- 主流 MySQL 索引结构是 B+ 树,叶子节点存数据/主键,范围查询快
- 聚簇索引:叶子节点直接存整行数据(一般主键索引)
- 非聚簇索引(二级索引):叶子存主键值,需回表再查
- 最左前缀原则:联合索引 (a, b, c) 能命中 a、a,b、a,b,c,不能单独命中 b 或 c
- 索引失效常见情况:WHERE 中对列做函数运算、隐式类型转换、LIKE ‘%xx’ 前置模糊、OR 连接非索引列
九、事务与隔离级别
ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 Read Uncommitted | 可能 | 可能 | 可能 |
| 读已提交 Read Committed | 否 | 可能 | 可能 |
| 可重复读 Repeatable Read(MySQL 默认) | 否 | 否 | 可能(InnoDB 靠间隙锁基本解决) |
| 串行化 Serializable | 否 | 否 | 否 |
十、高频手写题
- 查询第二高的薪水
SELECTMAX(salary)FROMemployeeWHEREsalary<(SELECTMAX(salary)FROMemployee);- 每个部门工资最高的员工(分组取 Top N 的简化版)
SELECTe.*FROMemployee eJOIN(SELECTdept,MAX(salary)ASmax_salFROMemployeeGROUPBYdept)tONe.dept=t.deptANDe.salary=t.max_sal;- 分组计数并过滤
SELECTdept,COUNT(*)FROMemployeeGROUPBYdeptHAVINGCOUNT(*)>=5;十一、口诀速记
- 执行顺序:FROM WHERE 分组 HAVING 选 ORDER LIMIT
- JOIN:INNER 交集,LEFT 左全,RIGHT 右全
- WHERE 与 HAVING:WHERE 过滤行,HAVING 过滤组
- 索引:最左前缀、函数失活、模糊前置失效