SQL数据库面试题精选,从基础到高级,助你轻松拿下Offer
这份《SQL数据库面试题精选》是助力求职者高效梳理薄弱、精准备考、拿下心仪技术Offer的实用资料,它覆盖从基础到高级的高频核心内容:基础如SELECT子句、JOIN关联、分组聚合;进阶高频如索引设计调优、事务ACID、锁机制解析;均配有专业简洁解析,适配应届生、跨行者及社招转岗/进阶技术人员。
在数据分析、后端开发、数据工程师等岗位的面试中,SQL几乎是必考项——它不仅是处理数据的核心工具,更能体现候选人对数据逻辑的理解能力,为了帮大家高效备考,我们整理了从基础到高级的经典SQL面试题,附详细解析和示例答案,让你面试时胸有成竹!
基础篇:核心概念与常用操作
这部分是面试的“敲门砖”,主要考察你对SQL基本语法和核心概念的掌握,几乎每个岗位都会问到。
基础SELECT查询:去重、排序与条件过滤
有一张“员工表(employee)”,包含字段:id(员工ID)、name(姓名)、department(部门)、salary(薪资),请写出SQL:
- 查询所有员工的姓名和部门;
- 查询薪资大于8000的员工,按薪资降序排列;
- 查询有哪些不同的部门(去重)。
解析:
- 基础查询用
SELECT指定列,FROM指定表; - 条件过滤用
WHERE,排序用ORDER BY(降序加DESC,默认升序ASC); - 去重用
DISTINCT关键字。
示例答案:
-- 查询姓名和部门 SELECT name, department FROM employee; -- 查询薪资>8000的员工并降序 SELECT * FROM employee WHERE salary > 8000 ORDER BY salary DESC; -- 查询不同部门(去重) SELECT DISTINCT department FROM employee;
WHERE vs HAVING:别再搞混!
WHERE和HAVING都用于过滤数据,它们的区别是什么?请举例说明。
解析:
这是最经典的基础题,核心区别在于过滤时机:
WHERE:在数据分组前过滤,不能直接用聚合函数(如SUM、COUNT);HAVING:在数据分组后过滤,通常和GROUP BY一起使用,可结合聚合函数。
示例:
比如要查询“部门平均薪资大于10000的部门”:
-- 错误:WHERE不能直接用聚合函数 SELECT department, AVG(salary) FROM employee WHERE AVG(salary) > 10000 GROUP BY department; -- 正确:用HAVING在分组后过滤 SELECT department, AVG(salary) AS avg_salary FROM employee GROUP BY department HAVING AVG(salary) > 10000;
JOIN的类型与区别:内连接、左连接、右连接…
SQL中有哪些常见的JOIN类型?分别解释它们的作用,并举例说明。
解析:
JOIN是SQL的核心,面试几乎必问,常见类型及区别:
- 内连接(INNER JOIN):只返回两张表中匹配成功的行(默认JOIN就是INNER JOIN);
- 左连接(LEFT JOIN):返回左表的所有行,右表匹配不到的地方用
NULL填充; - 右连接(RIGHT JOIN):返回右表的所有行,左表匹配不到的地方用
NULL填充; - 全外连接(FULL JOIN):返回左右表的所有行,匹配不到的用
NULL填充(部分数据库如MySQL不直接支持,可用UNION实现)。
示例:
假设有“学生表(student)”和“成绩表(score)”,student.id = score.student_id:
-- 内连接:只返回有成绩的学生 SELECT s.name, sc.score FROM student s INNER JOIN score sc ON s.id = sc.student_id; -- 左连接:返回所有学生,没成绩的score列是NULL SELECT s.name, sc.score FROM student s LEFT JOIN score sc ON s.id = sc.student_id;
GROUP BY与聚合函数
请用SQL统计每个部门的员工人数和最高薪资。
解析:
GROUP BY用于对数据分组,结合聚合函数(COUNT、MAX、MIN、SUM、AVG)使用,注意:SELECT中的列要么是GROUP BY的列,要么是聚合函数。
示例答案:
SELECT department, COUNT(*) AS employee_count, -- 统计人数 MAX(salary) AS max_salary -- 统计最高薪资 FROM employee GROUP BY department;
进阶篇:实用技巧与高频考点
这部分考察你解决复杂问题的能力,是拉开差距的关键,也是中高级岗位的重点。
子查询与临时表:解决“嵌套”问题
查询“薪资高于公司平均薪资”的员工姓名和薪资。
解析:
需要先计算公司平均薪资,再用这个结果作为条件过滤员工,可以用子查询或临时表实现。
示例答案:
-- 方法1:子查询 SELECT name, salary FROM employee WHERE salary > (SELECT AVG(salary) FROM employee); -- 方法2:临时表(更清晰,适合复杂逻辑) WITH avg_salary AS ( SELECT AVG(salary) AS avg_s FROM employee ) SELECT e.name, e.salary FROM employee e, avg_salary a WHERE e.salary > a.avg_s;
窗口函数:排名、分组统计的神器
有一张“成绩表(score)”,包含student_id(学生ID)、class(班级)、score(分数),请查询每个班级中分数排名前3的学生(如果分数相同,排名不跳过)。
解析:
窗口函数(如ROW_NUMBER()、RANK()、DENSE_RANK())是面试高频考点,核心是PARTITION BY(分组)和ORDER BY(排序):
ROW_NUMBER():按顺序给行编号,相同分数也会有不同排名;RANK():相同分数排名相同,后续排名跳过(如1、1、3);DENSE_RANK():相同分数排名相同,后续不跳过(如1、1、2)。
本题要求“排名不跳过”,用DENSE_RANK()。
示例答案:
WITH ranked_score AS (
SELECT
student_id,
class,
score,
DENSE_RANK() OVER (PARTITION BY class ORDER BY score DESC) AS rank_num
FROM score
)
SELECT * FROM ranked_score WHERE rank_num <= 3;
NULL值的处理:别让“空”坑了你
如何判断字段是否为NULL?如何将NULL替换为其他值?
解析:
NULL不是空字符串,也不是0,不能用= NULL或!= NULL判断,必须用IS NULL或IS NOT NULL,替换NULL常用COALESCE函数(返回第一个非NULL值)。
示例答案:
-- 查询没有填写部门的员工(department为NULL) SELECT * FROM employee WHERE department IS NULL; -- 将NULL部门替换为“待分配” SELECT name, COALESCE(department, '待分配') AS department FROM employee;
高级篇:性能优化与底层原理
这部分考察你对SQL“内功”的理解,适合中高级开发、DBA或数据工程师岗位。
事务的ACID特性
什么是事务?请解释事务的ACID特性。
解析:
事务是一组SQL操作的集合,要么全部成功,要么全部失败,ACID是事务的核心特性:
- 原子性(Atomicity):事务是不可分割的最小单位,要么全做,要么全不做;
- 一致性(Consistency):事务执行前后,数据库从一个一致状态到另一个一致状态(比如转账前后总金额不变);
- 隔离性(Isolation):多个事务并发执行时,互不干扰;
- 持久性(Durability):事务提交后,数据永久保存,即使系统故障也不丢失。
聚集索引 vs 非聚集索引
聚集索引和非聚集索引的区别是什么?一个表可以有几个聚集索引?
解析:
索引是提升查询性能的关键,两者核心区别是数据存储方式:
- 聚集索引:决定数据的物理存储顺序,一个表只能有1个(通常是主键);
- 非聚集索引:存储的是“索引列+指向数据行的指针”,物理存储顺序与索引顺序无关,一个表可以有多个。
简单理解:聚集索引像字典的“拼音目录”,数据按拼音顺序排列;非聚集索引像“部首目录”,目录顺序和正文顺序无关。
SQL性能优化的常见方法
你有哪些SQL性能优化的经验?请列举3-5个。
解析:
性能优化是高级岗位必问,常见方法:
- 避免
SELECT *,只查需要的列; - 合理建索引(在WHERE、JOIN、ORDER BY的列上建,但不要过度建索引,会影响写入性能);
- 避免在WHERE子句中对字段用函数(如
WHERE YEAR(create_time) = 2023,会让索引失效); - 用
LIMIT限制返回行数,避免全表扫描; - 大表查询时,考虑分页或分表分库。
面试通关小技巧
除了背题,这些技巧能帮你加分:
- 展示思路,不只给答案:比如面试官问JOIN,先讲“我会先考虑需要保留哪张表的数据,再选左连接还是内连接”,而不是直接写SQL;
- 结合项目经验:如果做过“统计订单数据”的项目,可以说“我之前用窗口函数统计过每个用户的订单排名,和这个题类似”;
- 遇到不会的别慌:可以说“这个问题我现在不太确定,但我会从XX角度思考”(我会先查索引的底层结构,或者试试EXPLAIN看执行计划”),展示你的思考过程。
SQL面试的核心是“理解逻辑+熟练应用”,建议大家把这些题动手写一遍,结合实际场景练习,只要把基础打牢,再掌握高频考点,就能轻松应对面试!
最后祝大家都能拿到心仪的Offer~

