跳至内容

2026 年最全 99 道 SQL 面试题与答案

为求职者、招聘经理和招聘人员提供必备 SQL 面试题与答案的全面概览,助您面试就绪。
更新 2026年4月30日  · 15分钟

无论您是在寻找新机会以施展 SQL 技能的求职者,还是即将在公司为岗位空缺考察候选人的招聘经理,掌握常见 SQL 面试题与答案都是必不可少的。

本文汇总了 2026 年的 99 道 SQL 面试题与答案,覆盖关键 SQL 主题,帮助您高效备考、学习与招聘,包括:

  • 基础知识:对 RDBMS、键以及 SQL 方言的清晰定义。
  • 技术精通: 深入解析 DDL 与 DML、约束与索引。
  • 查询逻辑:阐释连接、子查询与聚合函数。
  • 实践应用:真实世界的编码方案,如查找第 n 高的值或去重。
  • 情景题:面试风格的问题,涵盖运行总计、重复检测、缺口分析等。

 若您希望进一步提升知识与技能,欢迎探索我们的数据工程云技术AWS 系列课程。

SQL 面试题速览

SQL 面试的脉络往往与人们实际学习这门语言的过程相呼应。

起步阶段,重点在于“词汇与语法”,例如了解什么是 join、SELECT 如何工作,以及 DDL 与 DML 的区别。

随着熟悉度提升,关注点会从“能否写出查询”转向“能否写出正确的查询”。您会开始理解何时该使用索引、为何范式化重要,以及 DELETETRUNCATE 等看似相近命令在底层表现上的细微差异。

到高级阶段,语法被视为默认掌握,真正的考验在于问题求解:使用窗口函数与 CTE 处理去重、NULL、并列与排名逻辑,并在事务、一致性与性能方面进行推理思考。 

针对中级实践者

  1. SQL 中的函数。您应了解聚合与标量函数,以及内置函数与用户自定义函数。

  2. 高级命令。问题可能涉及连接、主键与外键、索引以及 SQL 关系。

  3. 数据库设计。预期会被问到范式化、反范式化,以及 DELETETRUNCATEDROP 等语句的差异。

  4. 高级查询。您可能会被问到嵌套与相关子查询,以及如何执行特定任务(如查找某列的第 n 高值)。

通用 SQL 面试题

在进入技术问题之前,面试官可能会先询问您整体的 SQL 经验。\

即便您的 SQL 经验有限也不必担心:面试官多半已从您的简历了解这一点。既然他们仍愿意与您交流,说明您的背景已被认为与其公司相匹配。此外,只接触过一种 SQL 方言完全没问题。请记住,各种 SQL 方言的差异并不大。因此,熟悉其中一种已经为学习其他方言打下了坚实基础。

1. 什么是 SQL?

SQL 是结构化查询语言(Structured Query Language),用于与关系型数据库管理系统(RDBMS)交互,包括从表中获取、更新、插入与删除数据。

2. 什么是 SQL 方言?请举例。

各类 SQL 版本(免费与付费)也被称为 SQL 方言。所有 SQL 方言在语法上非常相似,仅在附加功能上存在细微差异。示例包括 Microsoft SQL Server、PostgreSQL、MySQL、SQLite、T-SQL 与 Oracle。

3. SQL 的主要应用是什么?

使用 SQL,我们可以:

  • 在数据库中创建、删除和更新表
  • 访问、操作与修改表中的数据
  • 从一张或多张表检索与汇总所需信息
  • 向表中添加或移除特定行或列

SQL 初学者面试题 

面试官可能会用较简单的问题来开启对话:

4. 什么是 SQL 语句?

也称为 SQL 命令。它是由字符组成的字符串,被 SQL 引擎解释为合法命令并据此执行。SQL 语句的示例包括 SELECTCREATEDELETEDROPREVOKE 等。

5. 什么是 SQL 查询?

查询是用 SQL 编写的一段代码,用于从数据库访问或修改数据。

SQL 查询分为两类:数据检索与数据修改。 前者用于检索所需数据(也包括对数据进行限制、分组、排序、跨表提取等),后者用于创建、添加、删除、更新与重命名数据。

6. 什么是 SQL 子查询?

又称内部查询,是放在另一个查询(外部查询)中的查询。子查询可以出现在 SELECTFROMWHEREUPDATE 等子句中。子查询也可以嵌套在另一个子查询中。最内层子查询会先执行,其结果被传递给包含它的查询(或子查询)。

7. 什么是 SQL 连接(join)?

用于基于表之间列的关系,组合并检索两张或多张表的记录的子句。您可以查看我们的SQL 连接教程以了解更多背景,并阅读关于SQL 连接面试题的专门指南。 

8. 什么是 SQL 注释?

对某段代码作用的可读性说明。SQL 代码注释可以是单行(以双连字符 -- 开头),也可以是多行(如下: /*comment_text*/)。当 SQL 引擎运行时,会忽略代码注释。添加注释的目的在于让未来阅读代码的人更容易理解。

9. 什么是 SQL 别名(alias)?

在执行某个 SQL 查询时,为表(或表中的列)临时指定的名称。别名用于提升代码可读性并让代码更精简。使用 AS 关键字引入别名:

SELECT col_1 AS column
FROM table_name;

技术类 SQL 面试题

下面进入技术类 SQL 面试题及其可能的参考回答。

回答技术问题时,最佳策略是尽可能给出精准的答案。冗长或跑题的回答可能会偏离重点,还可能引出您把握不太稳的问题。

总的来说,SQL 允许以多种方式查询数据库,并且能与 Python、R 等其他编程语言轻松集成,从而发挥组合优势。

10. 您了解哪些类型的 SQL 命令?

  • 数据定义语言(DDL) —— 用于定义与修改数据库结构。
  • 数据操作语言(DML) —— 用于访问、操作与修改数据库中的数据。
  • 数据控制语言(DCL) —— 用于控制用户对数据库中数据的访问,为特定用户或用户组授予或撤销权限。
  • 事务控制语言(TCL) —— 用于控制数据库中的事务。
  • 数据查询语言(DQL) —— 用于对数据库中的数据进行查询以检索所需信息。

11. 列举一些常见的 SQL 命令。

  • DDL: CREATEALTER TABLEDROPTRUNCATEADD COLUMN

  • DML: UPDATEDELETEINSERT

  • DCL: GRANTREVOKE

  • TCL: COMMITSET TRANSACTIONROLLBACKSAVEPOINT

  • DQL: —— SELECT

12. 什么是 DBMS?您了解哪些类型?

DBMS 指数据库管理系统,是用于对数据库中存储的数据执行各种操作的软件包,如访问、更新、整理、插入与删除数据。DBMS 有多种类型,如关系型、层次型、网络型、图型或面向对象型。这些类型基于系统中数据的组织、结构与存储方式进行划分。

13. 什么是 RDBMS?请举例。

RDBMS 指关系型数据库管理系统。它是最常用的 DBMS 类型,用于处理存储在多张彼此通过共享键相关联的表中的数据。SQL 语言旨在与 RDBMS 交互。RDBMS 的示例有 MySQL、PostgreSQL、Oracle、MariaDB 等。

14. SQL 中的表与字段是什么?

表是以行与列的形式存储的有组织的相关数据集合。字段是表中列的另一种称呼。

15. 您了解哪些类型的 SQL 子查询?

  • 单行 —— 返回至多一行。
  • 多行 —— 返回至少两行。
  • 多列 —— 返回至少两列。
  • 相关 —— 子查询与外部查询中的信息相关。
  • 嵌套 —— 子查询嵌套在另一个子查询之中。

16. 什么是约束?为何使用约束?

用于定义可输入到表各列中的数据类型的一组条件。约束确保表中的数据完整性,并阻止不期望的操作。

17. 您了解哪些 SQL 约束?

  • DEFAULT —— 为列提供默认值。

  • UNIQUE —— 只允许唯一值。

  • NOT NULL —— 只允许非空值。

  • PRIMARY KEY —— 只允许唯一且严格非空的值(NOT NULLUNIQUE)。

  • FOREIGN KEY —— 在两张或多张表之间提供共享键。

18. 您了解哪些类型的连接(join)?

  • (INNER) JOIN —— 仅返回在两张(或所有)表中满足既定连接条件的记录。它是默认的 SQL 连接。

  • LEFT (OUTER) JOIN —— 返回左表的所有记录,以及右表中满足连接条件的记录。

  • RIGHT (OUTER) JOIN —— 返回右表的所有记录,以及左表中满足连接条件的记录。

  • FULL (OUTER) JOIN —— 返回两张(或所有)表的所有记录。可视为左连接与右连接的组合。

注意 FULL OUTER JOIN 受 PostgreSQL、SQL Server、Oracle 以及 MySQL 8.0 及更高版本支持,但 MySQL 仅通过 UNION 模式实现;同时,SQLite 不支持 RIGHT JOIN,可通过 LEFT JOIN 配合 UNION 进行模拟。

19. SQL 中的主键是什么?

对表中的某一列(或多列)施加 PRIMARY KEY 约束,以确保该列中的值唯一且非空。换言之,主键NOT NULLUNIQUE 约束的组合。主键可唯一标识表中每条记录。

相关概念 — 代理键:代理键是人工生成的标识符(通常为递增整数或 UUID),独立于实际业务数据分配给每条记录。不同于自然键(如电子邮件地址),代理键在业务数据变更时保持稳定,因此在生产数据库中常被用作主键。

 每张表至多可定义一个 PRIMARY KEY(可为复合主键)。尽管并非所有引擎都强制要求,但PRIMARY KEY 强烈推荐使用。

20. SQL 中的唯一键是什么?

对表中的某一列(或多列)施加 UNIQUE 约束,以确保该列的值唯一,包括可能出现的 NULL 值(仅允许一个)。

注意: 

  • SQL Server:默认仅允许一个 NULL,除非使用筛选索引。
  • PostgreSQL / Oracle / MySQL:允许多个 NULL,因为 NULL <> NULL

21. 什么是外键? 

对表中的某一列(或多列)施加 FOREIGN KEY(或 UNIQUE 键)约束,将该列与另一张(或多张)表中的主键关联。外键的目的在于保持数据库中各表之间的关联关系。

22. 什么是 SQL 索引?

与数据库表相关的特殊数据结构,用于存储其重要部分并加速数据搜索与检索。索引对大型数据库尤为高效,能显著提升查询性能。

23. 您了解哪些类型的索引?

  • 唯一索引 —— 不允许表列中出现重复,从而有助于维护数据完整性。
  • 聚集索引 —— 定义表记录的物理存储顺序,并基于键值执行数据查找。一张表只能有一个聚集索引。
  • 非聚集索引 —— 维护的记录顺序与磁盘上实际数据的物理顺序不一致。即数据存储在一个位置,非聚集索引存储在另一个位置。一张表可以有多个非聚集索引。

24. 什么是模式(schema)?

由表、存储过程、索引、函数与触发器等数据库结构元素组成的集合。它展示数据库的整体架构,指明各对象之间的关系,并为对象定义不同的访问权限。参阅我们的数据库模式指南以深入理解。

25. 什么是 SQL 运算符?

在 SQL 查询中用于执行特定操作的保留字符、字符组合或关键字。SQL 运算符通常与 WHERE 子句配合使用,以设置数据筛选条件。

26. 您了解哪些类型的 SQL 运算符?

  • 算术+-*/ 等)

  • 比较><=>= 等)

  • 复合+=-=*=/= 等)

  • 逻辑ANDORNOTBETWEEN 等)

  • 字符串%_+^ 等)

  • 集合UNIONUNION ALLINTERSECTMINUS(或 EXCEPT))

27. 什么是子句(clause)?

施加在 SQL 查询上的条件,用于筛选数据以获得所需结果。示例包括 WHERELIMITHAVINGLIKEANDORORDER BY 等。

28. 与 SELECT 查询常搭配的语句有哪些?

最常见的包括 FROMGROUP BYJOINWHEREORDER BYLIMITHAVING

29. 如何在 SQL 中创建表?

使用 CREATE TABLE 语句。例如,要创建包含三个预定义数据类型列的表,可使用如下语法:

CREATE TABLE table_name (col_1 datatype,
                         col_2 datatype,
                         col_3 datatype);

30. 如何更新表?

使用 UPDATE 语句。语法为:

UPDATE table_name
SET col_1 = value_1, col_2 = value_2
WHERE condition;

31. 如何从数据库中删除表?

使用 DROP TABLE 语句。语法为: DROP TABLE table_name;

32. 如何获取表中的记录数?

使用 COUNT() 聚合函数,并以星号作为参数: SELECT COUNT(*) FROM table_name;

33. 如何对表中记录进行排序?

使用 ORDER BY 语句:

SELECT * FROM table_name
ORDER BY col_1;

可使用 DESC 关键字指定降序;否则默认升序。也可按多个列排序,并分别为每个列指定升序或降序。例如:

SELECT * FROM table_name
ORDER BY col_1 DESC, col_3, col_6 DESC;

34. 如何选择表中的所有列?

SELECT 语句中使用星号 *。语法为: SELECT * FROM table_name;

35. 如何选择两张表中的公共记录?

使用 INTERSECT 语句:

SELECT col1, col2 FROM table_1
INTERSECT
SELECT col1, col2 FROM table_2;

注意 INTERSECT 要求相同的列数与兼容的数据类型。

36. 什么是 DISTINCT 语句?如何使用?

它与 SELECT 语句配合,用于去除重复,仅返回表某列中的唯一值。语法为:

SELECT DISTINCT col_1
FROM table_name;

37. 什么是关系(relationships)?请举例。

关系是实体之间的联系与关联,本质上指一张或多张表之间如何相互关联。例如,我们可以在销售数据表与客户表中找到同一客户的 ID。

38. 什么是 NULL 值?与零或空格有何不同?

NULL 值表示表中某个单元格缺少数据。相比之下,零是合法的数值,空字符串是长度为零的合法字符串。

39. SQL 与 NoSQL 有何区别?

SQL 数据库是关系型、结构化的,使用预定义模式的表;而 NoSQL 数据库是非关系型、无模式的,旨在处理非结构化或半结构化数据。

40. 使用 SQL 数据库时有哪些常见挑战?

挑战包括针对大型数据集的性能调优、索引策略管理、用约束确保数据完整性、处理并发事务以及优化查询执行。

中级 SQL 面试题

41. 什么是公用表表达式(CTE)?

公用表表达式(CTE)是一个临时的命名结果集,您可以在 SELECT、INSERT、UPDATE 或 DELETE 语句中引用。CTE 能提升查询可读性,让您将复杂查询拆解为更简单、可复用的部分。语法使用 WITH 关键字:

WITH sales_summary AS (
  SELECT product_id, SUM(amount) AS total_sales
  FROM sales
  GROUP BY product_id
)
SELECT p.product_name, s.total_sales
FROM products p
JOIN sales_summary s ON p.id = s.product_id
WHERE s.total_sales > 10000;

CTE 尤其适用于递归查询(如组织结构等层级数据),以及需要多次引用同一子查询的场景。

42. 什么是窗口函数?它与聚合函数有何不同?

窗口函数在与当前行相关的一组行上执行计算,但不会像聚合函数那样将结果折叠为单行。它们使用 OVER() 子句来定义行窗口。

常见窗口函数包括:

  • ROW_NUMBER() —— 为每行分配唯一的连续编号
  • RANK() —— 对并列赋相同名次,并保留名次缺口
  • DENSE_RANK() —— 对并列赋相同名次,但不保留缺口
  • LAG() / LEAD() —— 访问上一行/下一行的数据
  • SUM() OVER()AVG() OVER() —— 运行或累积计算

示例:计算销售的运行总计

SELECT 
  order_date,
  amount,
  SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;

43. RANK()、DENSE_RANK() 与 ROW_NUMBER() 有何区别?

三者都是排名窗口函数,但处理并列的方式不同:

  • ROW_NUMBER() —— 即使并列也始终分配唯一的连续编号(1, 2, 3, 4...)
  • RANK() —— 并列行获得相同名次,随后名次跳号(1, 2, 2, 4...)
  • DENSE_RANK() —— 并列行获得相同名次,但不跳号(1, 2, 2, 3...)
SELECT 
  name, 
  score,
  ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num,
  RANK() OVER (ORDER BY score DESC) AS rank,
  DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;

在查找“第 n 高值”且要求并列共享同一名次时,使用 DENSE_RANK()

本节我们梳理最常见的中级 SQL 问答,帮助您明确面试官的期待。

44. SQL 中的函数是什么?

表示为完成某项任务而经常使用的一组 SQL 语句的数据库对象。函数接收一些输入参数,对其进行计算或其他处理,并返回结果。函数有助于提升代码可读性并避免重复相同代码片段。

45. 您了解哪些类型的 SQL 函数?

  • 聚合函数 —— 对提供列的多条(通常是分组后)记录进行计算,并返回单一值(通常按组)。
  • 标量函数 —— 针对每个单独的值进行计算并返回单一值。

另一方面,SQL 函数可分为内置函数(系统定义)与用户自定义函数(用户按自身需求创建)。

46. 您了解哪些 SQL 聚合函数?

  • AVG() —— 返回平均值

  • SUM() —— 返回总和

  • MIN() —— 返回最小值

  • MAX() —— 返回最大值

  • COUNT() —— 返回行数,包括含空值的行

47. 您了解哪些 SQL 标量函数?

  • LEN()(在其他 SQL 方言中为 LENGTH())—— 返回字符串长度(包含空格)

  • UCASE()(在其他 SQL 方言中为 UPPER())—— 将字符串转换为大写

  • LCASE()(在其他 SQL 方言中为 LOWER())—— 将字符串转换为小写

  • INITCAP() —— 将字符串转换为标题格式(即每个词首字母大写)

  • MID()(在其他 SQL 方言中为 SUBSTR())—— 提取子串

  • ROUND() —— 将数值四舍五入到指定小数位

  • NOW() —— 返回当前日期与时间

48. SQL 中的大小写处理函数是什么?

大小写处理函数是字符函数的子集,用于更改文本数据的大小写。借助这些函数,我们可以将数据转换为大写、小写或标题格式。

  • UCASE()(在其他 SQL 方言中为 UPPER())—— 转换为大写

  • LCASE()(在其他 SQL 方言中为 LOWER())—— 转换为小写

  • INITCAP() —— 转换为标题格式(每个词首字母大写)

49. SQL 中的字符处理函数是什么?

字符处理函数是字符函数的子集,用于修改文本数据。

  • CONCAT() —— 连接两个或更多字符串,将第二个字符串追加到第一个之后

  • SUBSTRING()/SUBSTR() —— 返回满足给定起止位置的子串

  • LENGTH()(在其他 SQL 方言中为 LEN())—— 返回字符串长度(包含空格)

  • REPLACE() —— 将字符串中所有匹配的子串替换为另一个子串

  • INSTR() —— 返回子串在字符串中的位置(数值)

  • LPAD()RPAD() —— 为右对齐/左对齐的值在左侧/右侧填充字符

  • TRIM() —— 移除字符串左端、右端或两端的所有指定字符及空白

50. 局部变量与全局变量有何区别?

局部变量只能在其声明所在的函数内部访问。相反,全局变量在任何函数之外声明,存储在固定的内存结构中,可在整个程序中使用。

51. SQL 与 PL/SQL 有何不同?

SQL 是用于查询与管理关系型数据库的标准语言,主要用于数据操作与检索。PL/SQL(Procedural Language/SQL)是 Oracle 数据库中的 SQL 扩展,包含循环、条件与异常处理等过程式编程结构,使得可在数据库内实现复杂的业务逻辑。我们还有一篇关于PL/SQL 面试题 Top 20 的文章,如果您确定会被问到 Oracle 相关知识,这是不错的复习资料。 

52. LEFT JOIN 与 LEFT OUTER JOIN 有何区别?

二者没有区别,可互换使用。SQL 允许省略 OUTER 关键字,因此 LEFT JOIN 只是 LEFT OUTER JOIN 的简写。两者都会返回左表全部记录以及右表中匹配的记录。

53. 什么是 SQL 索引(indexing)?它如何提升性能?

索引会创建一种特殊的数据结构,加速数据检索,使数据库能够更高效地定位行。它类似优化的查找表,减少全表扫描。然而,过多的索引会因维护开销而拖慢插入、更新与删除操作。

54. 什么是存储过程?与函数有何不同?

存储过程是一组预编译的 SQL 语句,作为一个单元执行以完成任务。过程可以修改数据或架构对象、管理事务,并返回零个或多个结果集。函数则通常用于 SQL 表达式,必须返回一个值(标量或表值),且在许多数据库中限制产生副作用。不同数据库的具体行为不同(如 T-SQL 有标量与表值函数;PostgreSQL 区分函数与过程)。

55. 使用 ORDER BY 时的默认排序是什么?如何更改?

默认为升序(NULLS FIRST/LAST 随数据库而异)。可在每列后使用 ASC/DESC 关键字:

SELECT * FROM table_name 
ORDER BY col_1 DESC;

56. 什么是 SQL 集合运算符?

  • UNION —— 返回两条查询之一获得的记录(去重)

  • UNION ALL —— 返回两条查询之一获得的记录(包含重复)

  • INTERSECT —— 返回两条查询都获得的记录

  • EXCEPT(在 MySQL 与 Oracle 中称为 MINUS)—— 仅返回第一条查询获得而第二条未获得的记录

57. 查询中用于模式匹配的运算符是什么?

使用 LIKE 运算符配合 %_ 通配符。 % 表示任意数量(含 0 个)字符,_ 表示严格一个字符。

58. 主键与唯一键有何区别?

两者都确保表某列的值唯一,但主键用于唯一标识每条记录,而唯一键用于防止该列出现重复值。

59. 什么是复合主键?

基于多列构成的表主键。

60. SELECT 语句中常见子句的一般书写顺序是什么?

SELECTFROMJOINONWHEREGROUP BYHAVINGORDER BYLIMIT

61. 解释器执行 SELECT 查询中常见语句的顺序是什么?

如下是SQL 执行顺序: 

FROMONJOINWHEREGROUP BYHAVINGSELECTORDER BYLIMIT/OFFSET (FETCH)

62. SQL 中的视图是什么?

一种虚拟表,包含从一张或多张数据库表(或其他视图)检索的部分数据。 标准视图不存储数据;物化视图会存储。视图可以简化查询、封装逻辑,并结合权限限制列/行。它们可以从多表进行连接/聚合。

63. 可以基于另一个视图创建视图吗?

可以。这也称为嵌套视图。但应避免多层嵌套,会使代码难以阅读与调试。

64. 如果原表被删除,视图还能使用吗?

不能。删除基础表后,基于其创建的任何视图都会失效。如仍尝试使用,会收到错误信息。

65. 您了解哪些类型的 SQL 表关系?

  • 一对一 —— 一张表中的每条记录只对应另一张表中的一条记录
  • 一对多 —— 一张表中的每条记录对应另一张表中的多条记录
  • 多对多 —— 两张表中的每条记录都可对应对方表中的多条记录

66. BOOLEAN 字段可能的取值有哪些?

在某些 SQL 方言(如 PostgreSQL)中,BOOLEAN 类型明确存在,可取 TRUEFALSENULL。在其他方言(如 Microsoft SQL Server)中,使用 BIT 类型,以整数 1(true)或 0(false)存储布尔值。

67. 什么是 SQL 中的范式化(Normalization)?

范式化是数据库设计过程,通过组织与重构数据来减少冗余、依赖、重复与不一致。其结果是提升数据完整性、增加数据库中的表数量、更高效的数据访问与安全控制,以及更灵活的查询。

68. 什么是 SQL 中的反范式化(Denormalization)?

反范式化与范式化相反:它引入数据冗余,并将多张表的数据合并。在读操作重于写操作的场景中,反范式化通过避免复杂连接、减少查询运行时间,从而优化数据库基础设施的性能。

69. 重命名列与为列设别名有何不同?

重命名列是永久更改原表中该列的实际名称;设别名是仅在执行某条 SQL 查询时临时命名,以提升代码可读性与简洁性。

70. 嵌套子查询与相关子查询有何区别?

相关子查询是嵌套在更大(外部)查询中的内部查询,执行时引用外部查询的值,即相关子查询依赖其外部查询。相反,非相关子查询不依赖外部查询中的数据,可独立运行。

71. 聚集索引与非聚集索引有何区别?

聚集索引定义表记录的物理存储顺序,并基于键值执行数据查找;非聚集索引维护的记录顺序与磁盘上数据的物理顺序不一致。一张表只能有一个聚集索引,但可以有多个非聚集索引。

72. 什么是 CASE() 函数?

在 SQL 中实现 if-then-else 逻辑的方式。该函数依次检查 WHEN 子句中的条件,并在第一个条件满足时返回对应 THEN 子句的值;若均不满足,则返回 ELSE 子句的值(如提供),否则返回 NULL。语法如下:

CASE
    WHEN condition_1 THEN value_1
    WHEN condition_2 THEN value_2
    WHEN condition_3 THEN value_3
    ...
    ELSE value
END;

73. DELETE 与 TRUNCATE 有何区别?

DELETE 是 DML(数据操作语言)命令,用于根据 WHERE 子句中的条件删除一行或多行。仅当置于事务中(通过 ROLLBACK)时才可回滚。

TRUNCATE 是 DDL(数据定义语言)命令,通过释放数据页删除表中所有行。它更快但通常不可逆,且无法用于被外键引用的表。

74. DROP 与 TRUNCATE 有何区别?

DROP 会将表从数据库中彻底删除,包括表结构及所有相关约束、与其他表的关系和访问权限。 TRUNCATE 则删除表中所有行,但不影响表结构与约束。  二者均为 DDL。 DROP 删除表及其元数据;TRUNCATE 删除所有行但保留表定义。性能与事务行为取决于数据库引擎。

75. HAVING 与 WHERE 有何区别?

前者在分组与聚合之后对聚合结果起作用,后者逐行检查。若两者同时出现在查询中,顺序为:WHEREGROUP BYHAVING。SQL 引擎的解释顺序亦相同。

76. 如何向表中添加记录?

使用 INSERT INTO 配合 VALUES。语法为:

INSERT INTO table_name
VALUES (value_1, value_2, ...);

77. 如何从表中删除记录?

使用 DELETE 语句。语法为:

DELETE FROM table_name
WHERE condition;

也可以在满足条件时删除多条记录。

78. 如何向表中添加列?

使用 ALTER TABLE 配合 ADD。语法为:

ALTER TABLE table_name
ADD column_name datatype;

79. 如何重命名表中的列?

使用 ALTER TABLE 配合 RENAME COLUMN ... TO ...。语法为:

ALTER TABLE table_name
RENAME COLUMN old_column_name TO new_column_name;

80. 如何从表中删除列?

使用 ALTER TABLE 配合 DROP COLUMN。语法为:

ALTER TABLE table_name
DROP COLUMN column_name;

81. 如何选择表中所有偶数行或奇数行记录?

通过判断除以 2 的余数。在某些 SQL 版本(如 PostgreSQL 与 MySQL)中使用 MOD 函数,在另一些(Microsoft SQL Server 与 SQLite)中使用取模运算符(%)。选择所有偶数记录(使用 MOD):

SELECT * FROM table_name
WHERE MOD(ID_column, 2) = 0;

选择所有偶数记录(使用 %):

SELECT * FROM table_name 
WHERE ID_column % 2 = 0;

选择所有奇数记录时,两种写法相同,只需将 = 改为不等运算符 <>

82. 如何在查询时防止重复记录?

SELECT 中使用 DISTINCT,或为该表创建唯一键。

83. 如何向表中插入多行?

使用 INSERT INTO 配合 VALUES。语法为:

INSERT INTO table_name
VALUES (value_1, value_2, ...),
      (value_3, value_4, ...),
      (value_5, value_6, ...),
      ...;

84. 如何查找表某列中的第 n 高值?

使用窗口函数以正确处理并列:

SELECT column_name
FROM (
  SELECT column_name, DENSE_RANK() OVER (ORDER BY column_name DESC) AS rnk
  FROM table_name
) t
WHERE rnk = :n;

若按顺序取第 n 行(忽略并列):ORDER BY column_name DESC OFFSET n-1 ROWS FETCH NEXT 1 ROW ONLY。

85. 如何查找文本列中以某个字母开头的值?

使用 LIKE 运算符配合 %_ 通配符。例如需要查找表中所有以 “A” 开头的姓氏,查询如下:

SELECT * FROM table_name
WHERE surname LIKE 'A_';

这里我们假设姓氏至少包含两个字母。若不做此假设(即姓氏可能仅为 A),查询如下:

SELECT * FROM table_name
WHERE surname LIKE 'A%';

86. 如何查找表中最后一个 id?

最简单的方法是使用 聚合函数 MAX()

SELECT MAX(id) AS highest_id
FROM table_name;

使用 ORDER BY 配合 LIMITTOP

SELECT id
FROM table_name
ORDER BY id DESC
LIMIT 1;

87. 如何从表中随机选择行?

使用 RAND() 函数配合 ORDER BYLIMIT。在某些 SQL 方言(如 PostgreSQL)中称为 RANDOM()。例如,以下代码将在 MySQL 中返回 5 行随机记录:

SELECT * FROM table_name
ORDER BY RAND()
LIMIT 5;

情景题:SQL 面试题

情景题考察您用 SQL 解决真实业务问题的能力。面试官不仅评估您的语法知识,也关注您的问题求解方法,以及处理重复、NULL 值与并列等边界情况的能力。

88. 如何查找并移除表中的重复记录?

查找重复:

SELECT email, COUNT(*) AS duplicate_count
FROM users
GROUP BY email
HAVING COUNT(*) > 1;

移除重复(保留一条):

WITH duplicates AS (
  SELECT id, 
         ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn
  FROM users
)
DELETE FROM users 
WHERE id IN (SELECT id FROM duplicates WHERE rn > 1);

该方法使用带 ROW_NUMBER() 的 CTE 标识重复项,保留最小 ID 的记录。

89. 如何计算运行总计(累积和)?

使用带 ORDER BYSUM() 窗口函数:

SELECT 
  transaction_date,
  amount,
  SUM(amount) OVER (ORDER BY transaction_date) AS running_total
FROM transactions;

按类别(如每位客户)计算运行总计:

SELECT 
  customer_id,
  transaction_date,
  amount,
  SUM(amount) OVER (
    PARTITION BY customer_id 
    ORDER BY transaction_date
  ) AS customer_running_total
FROM transactions;

90. 如何查找部门内薪资高于平均水平的员工?

这是经典的相关子查询场景:

SELECT e.name, e.department, e.salary
FROM employees e
WHERE e.salary > (
  SELECT AVG(salary) 
  FROM employees 
  WHERE department = e.department
);

或使用窗口函数:

SELECT name, department, salary
FROM (
  SELECT 
    name, 
    department, 
    salary,
    AVG(salary) OVER (PARTITION BY department) AS dept_avg
  FROM employees
) t
WHERE salary > dept_avg;

91. 如何查找数列中的缺口(如缺失的发票号)?

使用 LEAD() 比较当前值与下一个值:

SELECT 
  invoice_number,
  LEAD(invoice_number) OVER (ORDER BY invoice_number) AS next_invoice,
  LEAD(invoice_number) OVER (ORDER BY invoice_number) - invoice_number - 1 AS gap_size
FROM invoices
WHERE LEAD(invoice_number) OVER (ORDER BY invoice_number) - invoice_number > 1;

该方法能识别相邻发票号间隔大于 1 的位置。

92. 如何查找在连续月份都有购买的客户?

使用 LAG() 与上一行比较:

WITH monthly_purchases AS (
  SELECT 
    customer_id,
    DATE_TRUNC('month', purchase_date) AS purchase_month,
    LAG(DATE_TRUNC('month', purchase_date)) OVER (
      PARTITION BY customer_id 
      ORDER BY DATE_TRUNC('month', purchase_date)
    ) AS prev_month
  FROM purchases
  GROUP BY customer_id, DATE_TRUNC('month', purchase_date)
)
SELECT DISTINCT customer_id
FROM monthly_purchases
WHERE purchase_month = prev_month + INTERVAL '1 month';

93. 如何将行转列(透视)?

使用带 CASE 的条件聚合:

SELECT 
  product_name,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
  SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_name;

部分数据库(SQL Server、Oracle)对此提供原生 PIVOT 语法。

94. 如何在每个品类中找出销量排名前三的产品?

使用 DENSE_RANK() 配合 PARTITION BY

WITH ranked_products AS (
  SELECT 
    category,
    product_name,
    SUM(sales_amount) AS total_sales,
    DENSE_RANK() OVER (
      PARTITION BY category 
      ORDER BY SUM(sales_amount) DESC
    ) AS sales_rank
  FROM sales
  GROUP BY category, product_name
)
SELECT category, product_name, total_sales
FROM ranked_products
WHERE sales_rank <= 3
ORDER BY category, sales_rank;

95. 数据库事务中的 ACID 特性是什么?

ACID 是保障数据库事务可靠性的四个关键特性的首字母缩写:

  • 原子性(Atomicity):事务是“要么全成,要么全不成”——所有操作要么全部成功,要么全部不执行
  • 一致性(Consistency):事务应使数据库从一个有效状态转移到另一个有效状态,遵循所有已定义的规则与约束
  • 隔离性(Isolation):并发事务互不干扰;每个事务看到的数据视图是一致的
  • 持久性(Durability):事务一旦提交,其变化将持久保存,即使系统崩溃也不会丢失

示例事务:

BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

COMMIT;

96. 什么是死锁?如何预防?

当两个或以上事务相互等待对方释放锁,从而形成循环依赖、均无法继续时,就发生了死锁。

示例场景:事务 A 锁住表 X 并等待表 Y,而事务 B 锁住表 Y 并等待表 X。

预防策略:

  • 一致的加锁顺序:在所有事务中按相同顺序获取锁
  • 保持事务简短:尽快提交或回滚
  • 使用合适的隔离级别:较低隔离级别可减少锁竞争
  • 仅访问必要数据:避免锁定不需要的行
  • 处理死锁重试:大多数数据库会自动检测并通过回滚一方事务来解除死锁

97. 如何优化运行缓慢的 SQL 查询?

关键优化策略:

  • 添加合适的索引:为出现在 WHEREJOINORDER BY 中的列建立索引

  • 分析执行计划:使用 EXPLAIN(PostgreSQL/MySQL)或 EXPLAIN PLAN(Oracle)定位瓶颈

  • 避免 SELECT *:只检索所需列

  • 使用 JOIN 替代子查询:JOIN 往往比相关子查询更高效

  • 限制返回集:当无需全部行时使用 LIMIT/TOP

  • 避免在索引列上使用函数:WHERE YEAR(date_col) = 2026 无法用到索引;改用 WHERE date_col >= '2026-01-01'

  • 考虑分区:对超大表按日期或类别进行分区

98. 在计算与比较中如何处理 NULL 值?

NULL 表示缺失或未知数据,需要特殊处理:

  • 比较:使用 IS NULLIS NOT NULL,而非 = NULL

  • COALESCE():返回第一个非 NULL 值:COALESCE(column, 'default')

  • NULLIF():若两值相等则返回 NULLNULLIF(a, b)

  • ISNULL() / NVL():特定数据库用于替换 NULL 的函数

SELECT 
  name,
  COALESCE(phone, email, 'No contact') AS contact_info,
  CASE WHEN status IS NULL THEN 'Unknown' ELSE status END AS status
FROM customers;

99. 如何找出用户连续登录天数的最长“连胜”纪录?

这是高级的“岛与桥”(连续段)问题:

WITH login_groups AS (
  SELECT 
    user_id,
    login_date,
    login_date - ROW_NUMBER() OVER (
      PARTITION BY user_id 
      ORDER BY login_date
    ) * INTERVAL '1 day' AS group_id
  FROM user_logins
)
SELECT 
  user_id,
  MIN(login_date) AS streak_start,
  MAX(login_date) AS streak_end,
  COUNT(*) AS streak_length
FROM login_groups
GROUP BY user_id, group_id
ORDER BY streak_length DESC
LIMIT 1;

技巧在于用每个日期减去行号——连续日期会得到相同的“group_id”。

用 SQL 为团队赋能

SQL 面试准备对求职者与招聘经理很重要,但对企业而言,为团队持续投入 SQL 培训同样关键。数据能力比以往任何时候都更重要,确保员工具备扎实的 SQL 技能,将成为公司成功的关键因素之一。

如果您是团队负责人或企业主,希望确保整个团队都能熟练掌握 SQL,DataCamp for Business 提供可定制的培训项目,帮助员工从基础到高级全面掌握 SQL 技能。我们可以提供:

  • 目标化学习路径:可根据团队当前技能水平与业务需求定制。
  • 动手实践:基于真实场景的练习以强化学习与提升记忆。
  • 进度追踪:用于监测与评估团队进展的工具,确保达成学习目标。

通过 DataCamp 等平台进行 SQL 技能提升,不仅增强团队能力,也为企业带来战略优势,助您保持竞争力并交付成果。欢迎联系我们的团队立即申请演示。 

结语

总而言之,本文讨论了 99 道覆盖初级、中级与情景题的核心 SQL 面试题及其正确答案。希望这些信息能帮助您备战面试、增强信心——无论您是在寻找 SQL 相关岗位,还是在为中级 SQL 职位招聘候选人。

如果您希望进一步训练以更好备考,欢迎浏览我们的SQL 课程完整清单:

FAQs

如何开始学习 SQL?

学习 SQL 可先从数据库基础与关系型数据库管理系统入门。DataCamp 提供了丰富资源,例如 Introduction to SQL 课程Data Analyst in SQL 职业路径以及SQL 备忘单。也可访问 SQL 课程页面浏览全部资源。

在哪里可以找到真实世界的 SQL 练习题?

在 DataCamp 平台上有许多适合各个水平的SQL 项目,可用于磨练技能。

有哪些常见的 SQL 初级面试题?

初学者常被问到基础概念,例如 SELECTINSERT 语句的区别、数据库中键(主键与外键)的作用,以及使用条件(WHERE 子句)从单表获取数据的简单查询。

有哪些常见的 SQL 中级面试题?

中级实践者可能会被问到更复杂的 SQL 概念,如连接(INNER、LEFT、RIGHT、FULL)、子查询、聚合与分组(GROUP BY),以及使用 UNION、INTERSECT、EXCEPT 等集合运算。此外,还可能被要求解决涉及查询性能优化的问题。

我该如何准备 SQL 面试?

准备 SQL 面试应包括:

  • 复习 SQL 基础与高级概念。
  • 练习编写解决常见问题的查询。
  • 了解数据库设计与范式化。
  • 熟悉用人单位使用的特定 SQL 方言(如 PostgreSQL、MySQL、SQL Server)。
  • 在线练习样题与问题。

技术类 SQL 面试会考什么?如何更好展示我的能力?

技术类 SQL 面试通常会考察您对 SQL 语法、数据库设计、查询优化以及用 SQL 解决问题的能力。要充分展示您的水平:

  • 在解题时清晰描述您的思路。
  • 准备好在白板或在线编码环境中写出无错误的 SQL 查询。
  • 通过示例展示对连接、子查询与事务等复杂概念的理解。
  • 分享您在数据库工作中的真实经验,突出解决过的挑战或做过的优化。

学习特定 SQL 方言重要吗?应优先关注哪些?

尽管 SQL 的核心语法在不同 RDBMS 中保持一致,但每个系统(如 MySQL、PostgreSQL、SQL Server、Oracle)都有各自的方言与独有特性与函数。若目标职位使用特定 RDBMS,学习对应的 SQL 方言很重要。请专注于最符合您职业目标或所在行业主流的方言。不过,扎实的标准 SQL 基础可让您更容易适应不同方言。

DataCamp 是否提供额外的免费资源来准备 SQL 面试?

当然!如果您目前是高校教师或学生,可通过 DataCamp Classrooms 免费获取我们的全部高级目录,其中包括 SQL 学习路径与认证。

您也可以查看我们的免费 SQL Basics 备忘单。

2026 年面试中最重要的 SQL 学习主题是什么?

请重点关注以下领域:(1)连接与子查询——理解 INNER、LEFT、RIGHT、FULL 连接,以及相关与非相关子查询;(2)窗口函数——ROW_NUMBER、RANK、DENSE_RANK、LAG、LEAD 与运行总计;(3)CTE(公用表表达式)——提升查询的可读性与可维护性;(4)聚合与 GROUP BY——包括 HAVING 子句的使用;(5)查询优化——索引策略与执行计划。

ROW_NUMBER、RANK 与 DENSE_RANK 有何区别?

三者都是用于排名的窗口函数,但处理并列的方式不同:ROW_NUMBER() 即使遇到并列也会分配唯一的连续编号(1、2、3、4);RANK() 对并列赋相同名次,但会跳过后续名次(1、2、2、4);DENSE_RANK() 对并列赋相同名次且不跳号(1、2、2、3)。在查找“第 n 高值”且需要并列共享名次时使用 DENSE_RANK。

主题

通过这些课程进一步学习 SQL!

Courses

Data Manipulation in SQL

4小时
318.1K
Master the complex SQL queries necessary to answer a wide variety of data science questions and prepare robust data sets for analysis in PostgreSQL.
查看详情Right Arrow
开始课程
查看更多Right Arrow