SQL数据库面试题精选,从基础到高级,助你轻松拿下Offer

2026-07-24 02:44:56 121阅读
这份《SQL数据库面试题精选》是助力求职者高效梳理薄弱、精准备考、拿下心仪技术Offer的实用资料,它覆盖从基础到高级的高频核心内容:基础如SELECT子句、JOIN关联、分组聚合;进阶高频如索引设计调优、事务ACID、锁机制解析;均配有专业简洁解析,适配应届生、跨行者及社招转岗/进阶技术人员。

在数据分析、后端开发、数据工程师等岗位的面试中,SQL几乎是必考项——它不仅是处理数据的核心工具,更能体现候选人对数据逻辑的理解能力,为了帮大家高效备考,我们整理了从基础到高级的经典SQL面试题,附详细解析和示例答案,让你面试时胸有成竹!

基础篇:核心概念与常用操作

这部分是面试的“敲门砖”,主要考察你对SQL基本语法和核心概念的掌握,几乎每个岗位都会问到。

SQL数据库面试题精选,从基础到高级,助你轻松拿下Offer

基础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:别再搞混!

WHEREHAVING都用于过滤数据,它们的区别是什么?请举例说明。

解析
这是最经典的基础题,核心区别在于过滤时机

  • WHERE:在数据分组前过滤,不能直接用聚合函数(如SUMCOUNT);
  • 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用于对数据分组,结合聚合函数(COUNTMAXMINSUMAVG)使用,注意: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 NULLIS 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个。

解析
性能优化是高级岗位必问,常见方法:

  1. 避免SELECT *,只查需要的列;
  2. 合理建索引(在WHERE、JOIN、ORDER BY的列上建,但不要过度建索引,会影响写入性能);
  3. 避免在WHERE子句中对字段用函数(如WHERE YEAR(create_time) = 2023,会让索引失效);
  4. LIMIT限制返回行数,避免全表扫描;
  5. 大表查询时,考虑分页或分表分库。

面试通关小技巧

除了背题,这些技巧能帮你加分:

  1. 展示思路,不只给答案:比如面试官问JOIN,先讲“我会先考虑需要保留哪张表的数据,再选左连接还是内连接”,而不是直接写SQL;
  2. 结合项目经验:如果做过“统计订单数据”的项目,可以说“我之前用窗口函数统计过每个用户的订单排名,和这个题类似”;
  3. 遇到不会的别慌:可以说“这个问题我现在不太确定,但我会从XX角度思考”(我会先查索引的底层结构,或者试试EXPLAIN看执行计划”),展示你的思考过程。

SQL面试的核心是“理解逻辑+熟练应用”,建议大家把这些题动手写一遍,结合实际场景练习,只要把基础打牢,再掌握高频考点,就能轻松应对面试!

最后祝大家都能拿到心仪的Offer~

文章版权声明:除非注明,否则均为亚朵原创文章,转载或复制请以超链接形式并注明出处。