当前位置:首页 > 问答 > 正文

SQL Server里头怎么把两张表连起来,举个简单的例子慢慢讲从零开始学连接操作

我们先来准备两张最简单的小表,你就把它们当成 Excel 里的两个小表格,这样好理解。

第一张表,叫 Employees(员工表)。 它有三列:

  • EmployeeID(员工编号):这个是每个员工的唯一号码,就像你的工牌号,不会重复。
  • EmployeeName(员工姓名):就是名字。
  • DepartmentID(部门编号):这个很重要,它表示这个员工属于哪个部门,注意,它只是个编号,不是部门的全名。

假设表里有这么几条数据:

EmployeeID EmployeeName DepartmentID
1 张三 101
2 李四 102
3 王五 101
4 赵六 NULL

你看,赵六的部门编号是 NULL,这表示他的部门还没定,或者信息缺失了,这一点待会儿会很关键。

第二张表,叫 Departments(部门表)。 它有两列:

  • DepartmentID(部门编号):和员工表里的那个部门编号是一回事。
  • DepartmentName(部门名称):部门的全名。

假设表里数据如下:

SQL Server里头怎么把两张表连起来,举个简单的例子慢慢讲从零开始学连接操作

DepartmentID DepartmentName
101 销售部
102 技术部
103 行政部

准备工作做完了,现在我们的目标是:生成一个新列表,里面有员工的姓名和他所在的部门名称,而不是那个看不懂的编号。

要实现这个目标,最常用、最基础的就是 INNER JOIN(内连接),你可以把它理解为“精确匹配的连接”,它只把两张表里能完全对应上的数据行拿出来拼在一起。

怎么拼呢?它的思路是: 拿左边表(员工表)的每一行,去右边表(部门表)里找,看看有没有一条记录的 DepartmentID 和当前这一行的 DepartmentID 相等,如果找到了,就把这两行数据合并成新的一行;如果找不到,左边表的这一行就扔掉不要了。

用 SQL 语句写出来是这样的:

SELECT
    Employees.EmployeeName,   -- 从员工表取姓名
    Departments.DepartmentName -- 从部门表取部门名
FROM
    Employees                 -- 左边的表是员工表
INNER JOIN
    Departments               -- 连接右边的部门表
ON
    Employees.DepartmentID = Departments.DepartmentID; -- 连接的条件是编号要相等

我们来一步步看这个语句:

SQL Server里头怎么把两张表连起来,举个简单的例子慢慢讲从零开始学连接操作

  1. SELECT ... FROM Employees:这表示我们要从员工表开始查询。
  2. INNER JOIN Departments:表示我要把部门表连接过来。
  3. ON Employees.DepartmentID = Departments.DepartmentID:这是连接的核心,叫做连接条件,它告诉 SQL Server 按照什么规则来拼表,这里规则就是两个表的部门编号必须一样。
  4. SELECT 后面选择了我们想看的列:员工姓名和部门名称。

执行上面这个查询,你会得到什么结果呢?

EmployeeName DepartmentName
张三 销售部
李四 技术部
王五 销售部

发现了吗?赵六不见了! 行政部(103)也不见了! 这就是 INNER JOIN 的特点:只返回两个表中都能匹配上的行。

  • 赵六的部门编号是 NULL,在部门表里找不到编号为 NULL 的部门,所以被丢掉了。
  • 行政部(103)在部门表里有,但在员工表里没有哪个员工的部门编号是 103,所以也被丢掉了。

这种连接在日常中用得最多,因为你通常只关心有关联的数据。

但有时候,你可能不想丢掉像赵六这样的员工,你想看到所有员工,即使他部门不明确,这时候就要用另一种连接了,叫做 LEFT JOIN(左连接)。

LEFT JOIN 的思路是:无论如何,都要保留左边表(员工表)的全部行。 然后去右边表(部门表)里找匹配的,如果找到了,就拼上部门名称;如果找不到(比如赵六),或者右边表没有对应的部门(比如行政部),那么来自右边表的所有列就用 NULL 来填充。

SQL Server里头怎么把两张表连起来,举个简单的例子慢慢讲从零开始学连接操作

我们把 SQL 语句里的 INNER JOIN 改成 LEFT JOIN

SELECT
    Employees.EmployeeName,
    Departments.DepartmentName
FROM
    Employees
LEFT JOIN  -- 这里改了,变成左连接
    Departments
ON
    Employees.DepartmentID = Departments.DepartmentID;

这次的结果是:

EmployeeName DepartmentName
张三 销售部
李四 技术部
王五 销售部
赵六 NULL

太好了,赵六保住了!虽然他的部门名称是 NULL,但至少这个人在名单里了,而行政部因为不是从左边表(员工表)出发需要的,所以依然不出现。

同理,还有 RIGHT JOIN(右连接),它就是反过来,无论如何保留右边表的全部行,以及 FULL JOIN(全连接),它是把 LEFT JOINRIGHT JOIN 的结果合起来,只要两边表里有的行,它都尽量保留,匹配不上的地方用 NULL 补全,因为不常用,这里就不细说了,你知道有这回事就行。

学连接最关键的三点:

  1. 想清楚以谁为主:你是要所有员工(用左连接),还是只要分配了部门的员工(用内连接)?
  2. 找对连接的条件ON 后面写的那个等式是关键,通常是两个表之间的那个“桥梁”字段(比如我们例子里的 DepartmentID)。
  3. 理解每种连接的结果:内连接是“交集”,左连接是“保左全”,右连接是“保右全”。

你完全可以像对照菜单点菜一样,需要哪种结果就用哪种连接,多试几次,用我们上面给的例子数据在 SQL Server 里跑一跑,改一改,感受一下区别,很快就明白了。