SQL Server的Inner Join及Outer Join

本文详细介绍了SQL中的多种连接类型,包括自然连接、交叉连接、内连接、外连接及其变种,并通过实例展示了Inner Join和Outer Join的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、NATURAL JOIN(自然连接)
    两张表通过NATURAL JOIN连接的时候,相当于有个隐含的WHERE子句,对两张表中同名的对应列相比较看是否相等。

二、CROSS JOIN(创建笛卡尔积)
    对两张表通过交叉联合产生第三张返回结果集的表。相当于普通的连接。

三、INNER JOIN(内连接)
   内连接就相当于普通的CROSS JOIN,只是格式不一样,INNER JOIN在后面有一个ON子句(相当于WHERE)的搜索条件,用于过滤返回的行。

四、OUTER JOIN (外连接)
   select * from ta outer join tb on (ta.c1=tb.c1)
    outer join告诉DBMS生成结果表,在此表中不仅带有相关(ta.c1=tb.c1)行对,而且还有来自两个源表中任一表的不匹配的行。

五、LEFT OUTER JOIN(左连接) RIGHT OUTER JOIN(右连接)
    select * from ta left outer join  tb on (ta.c1=tb.c1)
      select * from ta right outer join tb on (ta.c1=tb.c1)
      left outer join(left join) 告诉DBMS生成包括联合行和任何不匹配的行的结果表,但是不匹配的行系来自查询的FROM子句中LEFT OUTER JOIN关键词左边的表中。
    right outer join(right join)与left outer join(left join)刚好相反。

六、FULL OUTER JOIN(全连接)
   FULL OUTER JOIN 返回组合了LEFT OUTER JOIN 和RIGHT OUTER JOIN结果的表。

以下是Inner Join及Outer Join的具体介绍:

在一个正规化的数据库环境中, 我们常会碰到这款情形: 所需的资料并不是放在同一个资料表中, 在这个时候, 你就要用到 Join。

  当然 Join 如何将不同的数据库的资料结合, 还要看你如何使用它, 一共有四种不同的 Join 的方式, 在这篇文章中我们将为你介绍 Inner Join 及 Outer Join 以及其应用。

  Inner Join
  Inner Join 应该是最常用的 Join 方式, 它只会传回符合 Join 规则的纪录, 还是先来看看语法:
Select <要选择的字段> From <主要资料表> <Join 方式> <次要资料表> [On <Join 规则>]
  现在我们利用 MS SQL 内建的北风数据库来实际练习一下! 想多了解 MS SQL 的内建数据库, 你可以看看 SQL Server 的内建数据库这篇文章。

  请打开 QA (Query Analyzer), 为了使用北风数据库, 请先执行 Use Northwind, 然后执行
Select ProductId, ProductName, SupplierId From Products
  从 Products 产品资料表中取出三个字段, 分别是产品代码, 产品名称, 供货商代码, 但查询出来的结果保证让你的老板很不满意, 因为供货商代码对于人类实在是无什么意义, 这个时候 Join 就可以帮上忙了, 藉由 Join Suppliers 这个资料表我们便可以查询到供货商名称
Select ProductId, ProductName, Suppliers.SupplierId
From Products
Inner Join Suppliers on
Products.SupplierId= Suppliers.SupplierId
  这款的查询结果是不是清楚呢! Inner Join 的主要精神就是 exclusive , 叫它做排他性吧! 就是讲 Join 规则不相符的资料就会被排除掉, 譬如讲在 Product 中有一项产品的供货商代码 (SupplierId), 没有出现在 Suppliers 资料表中, 那么这笔记录便会被排除掉

  Outer Join
  这款的 Join 方式是一般人比较少用到的, 甚至有些 SQL 的管理者也从未用过, 这真是一件悲哀的代志, 因为善用 Outer Join 是可以简化一些查询的工作的, 先来看看 Outer Join 的语法

Select <要查询的字段> From <Left 资料表> <Left | Right> [Outer] Join <Right 资料表> On <Join 规则>

  语法中的 Outer 是可以省略的, 例如你可以用 Left Join 或是 Right Join, 在本质上, Outer Join 是 inclusive, 叫它做包容性吧! 不同于 Inner Join 的排他性, 因此在 Left Outer Join 的查询结果会包含所有 Left 资料表的资料, 颠倒过来讲, Right Outer Join 的查询就会包含所有 Right 资料表的资料, 接下来我们还是来做些实际操作, 仍然是使用北风数据库, 但要先做一些小小的修改, 才能达到我们要的结果。

  首先要拿掉 Products 资料表的 Foreign Key, 否则没有法度在 Products 资料表新增一笔 SupplierId 没有对映到 Suppliers 资料表的纪录, 要知影一个资料表的 Constraint 你可以执行 SQL 内建的 sp_helpconstraint , 在 QA 执行
sp_helpconstraint Products
  接下来删除 FK_Products_Suppliers 这个 Foreign Key
Alter Table Products
Drop Constraint FK_Products_Suppliers
  再来新增一笔纪录于 Products 资料表, SupplierId 使用 50 是因为它并没有对映到 Suppliers 资料表中的记录
Insert Into Products (ProductName,SupplierId,CategoryId)
values ('Test Product','50','1')
  现在我们再执行头前的查询, 只是将 Inner Join 改为 Left Outer Join
Select ProductId, ProductName, Suppliers.SupplierId
From Products
Left Outer Join Suppliers
Products.Suppliers = Suppliers.SupplierId
  比较一下两种 Join 方式的查询结果, 你应该就会知影其中的差别!
  再来看看 Right Outer Join, 请新增下底这笔记录
Insert Into Suppliers (CompanyName)
values ('LearnASP')
  现在请使用 Right Out Join 来作查询, 比较看看查询的结果和 Inner Join 有什么不同!
  寻找不相符纪录
  这里我们来看看如何使用 Out Join 来找不相符纪录, 可能是有子纪录却没有父纪录或是颠倒过来
Select Suppliers.CompanyName From Products
Right Join Suppliers
On Products.SupplierId = Suppliers.SupplierId
Where Products.SupplierId is Null

  执行结果你会找到一笔资料为 LearnASP, 该笔供货商资料存在, 但基本上已经没有产品是来自这个供货商, 想象一下如果不用 Outer Join 你要怎么以一个 SQL 指令完成同一查询结果! 知道 Outer Join 的好用了吧! 再执行
Select Products.ProductName
From Products
Left Join Suppliers
On Products.SupplierId = Suppliers.SupplierId
Where Suppliers.SupplierId is Null

  这个查询结果你会发现 Test Product 这项产品竟然找不到供货商的资料!

 
<think>好的,用户现在想了解SQL Server中的LEFT OUTER JOIN。我需要先回顾一下之前他问过的问题,之前他问过DATEDIFF,现在转向JOIN类型,可能是在学习SQL的不同部分。 首先,用户可能已经了解基本的JOIN概念,但需要明确LEFT OUTER JOIN的具体用法。我应该先定义LEFT OUTER JOIN的作用,强调它返回左表所有记录和右表匹配的记录,如果没有匹配,右表部分为NULL。 接下来,用户可能需要语法示例,这样他们可以直观地看到怎么写这个JOIN。要提供一个标准的语法结构,并解释每个部分的含义,比如ON子句的作用。 然后,对比LEFT OUTER JOININNER JOIN的区别很重要。用户可能混淆这两者,特别是刚学习的时候。用具体的例子说明两者的不同,比如当右表没有匹配时,INNER JOIN会排除左表的记录,而LEFT OUTER JOIN会保留。 实际应用场景能帮助用户理解何时使用这个JOIN。比如统计所有客户的订单,即使没有订单的客户也要显示,这时候LEFT OUTER JOIN就很有用。可能需要举一个具体的例子,包括表结构和查询语句,以及结果说明。 此外,用户可能对多个表的JOIN操作感兴趣,或者对性能有疑问。不过根据当前问题,可能不需要深入讨论性能优化,但可以提到在使用时需要注意索引和条件优化。 还要注意LEFT OUTER JOIN中的过滤条件位置,比如WHERE和ON的区别,这是一个常见的误区。比如在ON里过滤会影响JOIN结果,而在WHERE中则是在JOIN之后过滤,可能导致不同的结果。 最后,是否需要提及与其他JOIN类型的比较,比如RIGHT OUTER JOIN或FULL OUTER JOIN?可能简要提一下,但重点还是放在LEFT OUTER JOIN上。 总结一下,回答的结构应该是:定义、语法、与INNER JOIN的区别、应用场景、注意事项、示例。确保用中文清晰解释,避免术语混乱,并举例说明。检查是否有遗漏点,比如别名使用、多表连接,或者常见错误,比如条件放错位置。</think>### SQL Server 的 `LEFT OUTER JOIN` 逐步解析 `LEFT OUTER JOIN`(左外连接)是 SQL 中用于**关联两个表**的查询操作,其核心规则是:**保留左表的所有行,并匹配右表中符合条件的行;若无匹配,右表字段以 `NULL` 填充**。以下是详细解析: --- ### 一、基本语法 ```sql SELECT 列名 FROM 左表 LEFT OUTER JOIN 右表 ON 左表.关联列 = 右表.关联列; ``` - **关键字**:`LEFT OUTER JOIN`(可简写为 `LEFT JOIN`) - **ON 子句**:定义两个表的关联条件 - **结果**: - 左表所有行必然出现在结果中 - 右表仅返回匹配的行,无匹配时填充 `NULL` --- ### 二、与 `INNER JOIN` 的区别 | 特性 | LEFT OUTER JOIN | INNER JOIN | |---------------------|-------------------------------------|--------------------------------| | **左表未匹配的行** | 保留,右表字段为 `NULL` | 不保留 | | **右表未匹配的行** | 不保留(除非右表有其他关联条件) | 不保留 | | **结果集大小** | ≥ 左表行数 | ≤ 左表行数 | --- ### 三、典型应用场景 #### 1. **查询主表数据并关联补充信息** - **示例**:列出所有客户及其订单(即使客户没有订单) ```sql SELECT Customers.CustomerName, Orders.OrderID FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID; ``` - 结果包含所有客户,无订单的客户其 `OrderID` 为 `NULL`。 #### 2. **统计存在/不存在关联的记录** - **示例**:找出未下单的客户 ```sql SELECT Customers.CustomerName FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID WHERE Orders.OrderID IS NULL; ``` --- ### 四、注意事项 1. **关联条件位置**: - 过滤条件写在 `ON` 子句中:影响匹配逻辑(在关联时过滤右表) - 过滤条件写在 `WHERE` 子句中:在关联完成后过滤最终结果 2. **性能优化**: - 为关联列(如 `CustomerID`)添加索引 - 避免在右表中使用复杂条件导致全表扫描 3. **多表连接**: - 可链式使用多个 `LEFT JOIN`,但需注意顺序对结果的影响 ```sql SELECT * FROM TableA LEFT JOIN TableB ON TableA.ID = TableB.A_ID LEFT JOIN TableC ON TableB.ID = TableC.B_ID; ``` --- ### 五、示例演示 #### 表结构 - **`Employees` 表**: | EmployeeID | Name | |------------|--------| | 1 | 张三 | | 2 | 李四 | - **`Orders` 表**: | OrderID | EmployeeID | Amount | |---------|------------|--------| | 101 | 1 | 200 | | 102 | 1 | 300 | #### 查询 ```sql SELECT Employees.Name, Orders.OrderID, Orders.Amount FROM Employees LEFT JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID; ``` #### 结果 | Name | OrderID | Amount | |--------|---------|--------| | 张三 | 101 | 200 | | 张三 | 102 | 300 | | 李四 | NULL | NULL | --- ### 六、总结 `LEFT OUTER JOIN` 是处理**主从表关联**或**保留主表完整数据**的核心工具。使用时需明确: 1. 是否需要保留左表全部数据 2. 关联条件的准确性 3. 性能影响(尤其是大数据量场景)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值