Module 03 · Intermediate SQL
Sub-Queries and Nested Selects嵌套查询 (Subqueries) 详解
您好,欢迎学习本视频,您将了解如何编写子查询 (Subqueries) 或嵌套 SELECT 语句 (Nested Select Statements)。
什么是子查询?
子查询 (Subqueries),也称为子选择 (Sub-selects),是像常规查询一样,但被放置在圆括号内并嵌套在另一个查询中的查询。这使得您可以构建比单独查询更强大的查询。
- 嵌套示例: 如下图所示,子查询位于另一个查询的
WHERE** 子句**中。
在本课中,我们将使用一个包含 Employee_ID、First_Name、Last_Name、Salary 等列的 EMPLOYEES** 表**作为示例。

1 在WHERE子句中使用子查询
当聚合函数(如 AVG)不能直接在 WHERE 子句中评估时,子查询是解决此类限制的有效方法。
场景:查询薪资高于平均水平的员工
如果我们尝试直接使用聚合函数,查询会出错:
SQL
SELECT * FROM EMPLOYEES WHERE Salary > AVG(Salary);
❌ 结果: 运行此查询会导致错误,指示聚合函数使用无效。内置聚合函数(如
AVG)的限制之一是它们不能总是直接在WHERE子句中评估。
解决方法:使用子查询绕过限制
通过将聚合函数放在子查询中,可以先计算出平均薪资,再用于外部查询的 WHERE 子句进行比较:
SQL
SELECT Employee_ID, First_Name, Last_Name, Salary
FROM EMPLOYEES
WHERE Salary > (SELECT AVG(Salary) FROM EMPLOYEES);
- 原理: 子查询首先计算出平均薪资,然后外部查询使用这个单一值作为
WHERE子句的比较条件,从而绕过了聚合函数不能直接在WHERE子句中评估的限制。
2 在SELECT列列表中使用子查询(列表达式)
子查询不仅可以放在 WHERE 子句中,还可以放在要选择的列列表中。这类子查询被称为列表达式 (Column Expressions)。
场景:比较每位员工的薪资与平均薪资
如果我们想将每位员工的薪资与平均薪资进行比较,直接尝试如下查询会出错:
SQL
SELECT Employee_ID, Salary, AVG(Salary) AS Average_Salary FROM EMPLOYEES;
❌ 结果: 运行此查询将导致错误,指示未指定
GROUP BY子句。
解决方法:使用子查询作为列表达式
我们可以将 AVG 函数放入一个子查询中,并将其放置在列列表中:
SQL
SELECT Employee_ID, Salary,
(SELECT AVG(Salary) FROM EMPLOYEES) AS Average_Salary
FROM EMPLOYEES;
- 原理: 子查询作为一个列表达式,为外部查询返回的每一行计算并重复显示平均薪资。
3 在FROM子句中使用子查询(派生表)
子查询还可以作为 FROM** 子句的一部分。这类子查询有时被称为派生表 (Derived Tables)** 或表表达式 (Table Expressions),因为外部查询将子查询的结果用作其数据源。
场景:基于非敏感信息创建派生表
假设我们想创建一个只包含非敏感员工信息的派生表:
SQL
SELECT * FROM
(SELECT Employee_ID, First_Name, Last_Name, Department_ID FROM EMPLOYEES) AS Employee_For_All;
- 子查询 (内查询):
SELECT Employee_ID, First_Name, Last_Name, Department_ID FROM EMPLOYEES- 该子查询排除了敏感字段(如出生日期或薪资)。
- 外部查询:
SELECT * FROM (...) AS Employee_For_All- 外部查询使用子查询的结果集作为一个临时表(
Employee_For_All)。
- 外部查询使用子查询的结果集作为一个临时表(
虽然上例相对简单,但派生表在处理多表连接 (joins)** 或复杂情况时,能够极大地增强查询能力。
总结
在本视频中,您了解了子查询和嵌套查询如何用于形成更丰富的查询,并克服聚合函数的一些限制。
您学习了在以下位置使用子查询:
WHERE** 子句**- 列列表(列表达式)
FROM** 子句**(派生表/表表达式)