相关子查询教程

1. 概述

在SQL中,子查询是一种嵌套在其他查询中的查询。相关子查询(Correlated Subquery)是一种特殊的子查询,它依赖于外部查询的某些值。这意味着子查询的执行会受到外部查询的影响,每次外部查询的行发生变化时,子查询都会重新执行。

2. 理论解释

2.1 什么是相关子查询?

相关子查询是一种嵌套查询,其中子查询的执行依赖于外部查询的当前行。换句话说,子查询中的某些值是从外部查询中获取的。这种依赖性使得相关子查询在处理复杂查询时非常有用。

2.2 相关子查询的工作原理

  1. 外部查询:首先执行外部查询,获取一行数据。
  2. 子查询:然后执行子查询,子查询中的某些值是从外部查询的当前行中获取的。
  3. 结果返回:子查询的结果用于外部查询的条件判断,决定是否保留当前行。
  4. 重复:外部查询继续处理下一行,重复上述过程,直到所有行都被处理。

3. 代码示例

3.1 示例表结构

假设我们有两个表:Employees 和 Departments。

CREATE TABLE Employees (
    EmployeeID INT PRIMARY KEY,
    Name VARCHAR(50),
    DepartmentID INT,
    Salary DECIMAL(10, 2)
);

CREATE TABLE Departments (
    DepartmentID INT PRIMARY KEY,
    DepartmentName VARCHAR(50)
);

3.2 示例数据

INSERT INTO Employees (EmployeeID, Name, DepartmentID, Salary) VALUES
(1, 'Alice', 1, 50000),
(2, 'Bob', 2, 60000),
(3, 'Charlie', 1, 55000),
(4, 'David', 3, 70000);

INSERT INTO Departments (DepartmentID, DepartmentName) VALUES
(1, 'HR'),
(2, 'Engineering'),
(3, 'Sales');

3.3 相关子查询示例

假设我们想要查找每个部门的最高薪资员工。

SELECT e.Name, e.Salary, d.DepartmentName
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
WHERE e.Salary = (
    SELECT MAX(Salary)
    FROM Employees
    WHERE DepartmentID = e.DepartmentID
);

3.4 解释

  • 外部查询:从 Employees 表中选择员工信息,并连接 Departments 表以获取部门名称。
  • 子查询:子查询计算每个部门的最高薪资。注意,子查询中的 DepartmentID = e.DepartmentID 使得子查询依赖于外部查询的当前行。
  • 结果:外部查询使用子查询的结果来过滤出每个部门的最高薪资员工。

4. 实践练习

4.1 练习1:查找每个部门的最低薪资员工

编写一个SQL查询,查找每个部门的最低薪资员工。

SELECT e.Name, e.Salary, d.DepartmentName
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
WHERE e.Salary = (
    SELECT MIN(Salary)
    FROM Employees
    WHERE DepartmentID = e.DepartmentID
);

4.2 练习2:查找薪资高于部门平均薪资的员工

编写一个SQL查询,查找薪资高于其所在部门平均薪资的员工。

SELECT e.Name, e.Salary, d.DepartmentName
FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID
WHERE e.Salary > (
    SELECT AVG(Salary)
    FROM Employees
    WHERE DepartmentID = e.DepartmentID
);

5. 总结

相关子查询是SQL中一种强大的工具,特别适用于需要依赖外部查询结果的复杂查询场景。通过理解其工作原理和掌握相关子查询的使用方法,你可以更有效地处理和分析数据库中的数据。

6. 进一步学习

  • 表连接:学习如何使用 INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN 等连接方式来组合多个表的数据。
  • 聚合函数:深入了解 SUM, AVG, COUNT, MAX, MIN 等聚合函数的使用。
  • 窗口函数:探索窗口函数(Window Functions),它们可以在不使用子查询的情况下实现类似的功能。

通过不断练习和实践,你将能够熟练掌握相关子查询,并在实际项目中灵活应用。