Coursera 笔记

Module 03 · Intermediate SQL

Working with Multiple Tables多表访问查询:子查询与隐式连接

Coursera ↗

您好,欢迎学习本视频。在本视频中,您将学习如何编写访问多个表的查询。

有几种方法可以在同一个查询中访问多个表:

  1. 子查询 (Sub-queries)
  2. 隐式连接 (Implicit Join)
  3. 连接运算符 (Join Operators),例如 INNER JOIN 和 OUTER JOIN。

本视频将重点介绍前两种方法。第三种方法将在其他视频中详细介绍。

示例表结构

我们将使用以下两个表进行示例:

表名 关键列
EMPLOYEES (员工表) Employee_ID, First_Name, Last_Name, Salary, Dep_ID
DEPARTMENTS (部门表) Dept_ID_Dep, Department_Name, Manager_ID, Location_ID


1 使用子查询 (Sub-queries) 访问多表

在处理多表查询时,子查询允许我们使用一个查询的结果来过滤或作为另一个查询的输入。

场景一:根据部门 ID 过滤员工记录

检索 Employees 表中,其 Dep_ID 存在于 Departments 表中的所有员工记录。

SQL

SELECT * FROM Employees 
WHERE Dep_ID IN (SELECT Dept_ID_Dep FROM Departments);

  • 外部查询: 访问 Employees 表。
  • 子查询: 在 Departments 表上执行,用于为外部查询的结果集提供过滤条件。

场景二:根据位置 ID 过滤员工记录

检索位于特定位置(例如 L0002)的所有员工。Employees 表中没有位置信息,但 Departments 表中有 Location_ID。

SQL

SELECT * FROM Employees 
WHERE Dep_ID IN (SELECT Dept_ID_Dep FROM Departments WHERE LOC_ID = 'L0002');

  • 逻辑:
    1. 子查询首先从 Departments 表中找出 LOC_ID 为 L0002 的所有部门 ID。
    2. 外部查询使用这些部门 ID 来检索匹配的员工记录。

场景三:根据员工薪资检索部门信息

检索薪资超过 $70,000 的员工的部门 ID 和部门名称。

SQL

SELECT Dept_ID_Dep, Department_Name 
FROM Departments 
WHERE Dept_ID_Dep IN (SELECT Dep_ID FROM Employees WHERE Salary > 70000);

  • 逻辑:
    1. 子查询在 Employees 表上执行,获取薪资大于 $70,000 的员工的部门 ID。
    2. 外部查询将这些部门 ID 作为输入,从 Departments 表中获取匹配的部门名称。

2 使用隐式连接 (Implicit Join) 访问多表

您可以通过在查询的 FROM** 子句中指定多个表来访问它们,从而实现隐式连接**。

基础隐式连接 (笛卡尔积)

在 FROM 子句中指定两个表:

SQL

SELECT * FROM Employees, Departments;

  • 结果: 这会形成一个完全连接 (Full Join),也称为笛卡尔积 (Cartesian Product)。第一个表中的每一行都会与第二个表中的每一行连接。
  • 特点: 结果集中的行数将大于两个表各自的行数之和。

限制结果集(基于匹配列)

通常需要使用额外的操作数(例如 WHERE 子句)来限制结果集,使其仅包含具有匹配部门 ID 的行。

SQL

SELECT * FROM Employees, Departments 
WHERE Employees.Dep_ID = Departments.Dept_ID_Dep;

  • 完全限定列名: 在 WHERE 子句中,我们使用 TableName.ColumnName 的格式来完全限定 (fully qualify) 列名。这是必要的,因为不同的表可能拥有相同的列名(例如 ID),以避免歧义。

使用别名简化查询

由于表名可能很长,我们可以使用别名 (Aliases) 来简化查询。

SQL

SELECT * FROM Employees E, Departments D 
WHERE E.Dep_ID = D.Dept_ID_Dep;

  • 别名定义: 在 FROM 子句中,我们为 Employees 定义了别名 E,为 Departments 定义了别名 D。
  • 使用别名: 在 WHERE 子句中,使用这些别名来限定列名。

选择特定列并使用别名

如果只想查看员工 ID (EMP_ID) 和部门名称 (DEP_NAME):

SQL

SELECT E.Emp_ID, D.Department_Name 
FROM Employees E, Departments D 
WHERE E.Dep_ID = D.Dept_ID_Dep;

  • SELECT** 子句中的别名:** SELECT 子句中的列名也可以用别名来限定,这使查询更加清晰。

总结

在本课程中,您学习了如何使用以下方法处理多表查询:

  • 子查询: 用于根据另一个表的数据来过滤或输入外部查询。
  • 隐式连接: 通过在 FROM 子句中列出多个表来实现,并使用 WHERE** 子句和列名前缀/别名**来指定连接条件。