在 SQL Server 中查询多个表
介绍
在其他指南中,您已经学习了如何编写基本 SQL 查询来从表中检索数据。在实际应用中,您需要从多个表中获取数据才能实现目标。为此,您需要使用 SQL 连接。在本指南中,您将学习如何使用连接从多个表中查询数据。
了解连接
为了理解连接,您应该首先了解笛卡尔积的概念。在数学中,这是两个集合的乘积。例如,一组两个项目乘以一组六个项目将产生一组十二个项目。
在数据库中,笛卡尔积是将一个输入表的每一行与另一个表的所有行连接起来的结果。因此,一个两行表和一个三行表的乘积将是一组六行。
示例:订单和商品的笛卡尔积
表 1:订单
订单编号 |
---|
1 |
2 |
表 2:项目
物品编号 |
---|
1 |
2 |
3 |
结果:每行订单与每行商品相乘,结果如下。
订单编号 | 物品编号 |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
2 | 3 |
在 SQL 中,要从多个表中获取数据,需要使用连接运算符。连接运算符会在 SQL Server 用于处理数据的虚拟表中添加或删除行,然后再由查询的其他步骤使用数据。连接可以分为以下类别:
交叉连接,也称为笛卡尔积,将两个输入表的行的所有可能组合添加到虚拟表中。所有行的数据过滤都将在where子句中完成。
内连接运算符首先创建笛卡尔积,然后使用 ON 子句中提供的谓词过滤结果,从虚拟表中删除任何不满足谓词的行。这是最常用的连接类型。
外连接运算符(LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN)首先创建笛卡尔积,然后过滤结果以查找每个表中匹配的行。不同之处在于,在应用初始过滤器后,一个表中的所有行都会保留并添加回虚拟表。所有空值都放置在未找到匹配值的属性上。
使用内连接
内连接用于检索存储在多个表中的数据。如前所述,内连接以笛卡尔积的形式开始其逻辑处理阶段,然后进行过滤以删除与谓词不匹配的任何行。
值得注意的是,INNER JOINS 仅返回在两个输入表中找到匹配的行。
内连接语法如下:
SELECT o.orderid, o.amount, i.description
FROM orders o
INNER JOIN items i
ON o.itemid = i.itemid
上面的查询中需要注意的一些关键元素:
- 注意 FROM、SELECT 和 ON 语句中别名的使用。订单表的别名为o,在 ON 语句和 SELECT 语句中均有使用。
- 关键字 INNER JOIN 可以仅表示为 JOIN。两个表达式都表示内连接。
- 因为我们使用的是 INNER JOIN,所以结果只会是两个表中都存在的行。
内连接示例
请考虑下表。
餐桌订单
订单编号 | 物品编号 | 数量 |
---|---|---|
1 | 1 | 3 |
2 | 2 | 4 |
3 | 2 | 1 |
4 | 3 | 1 |
表项
物品编号 | 商品价格 | 项描述 |
---|---|---|
1 | 10 | 东西 |
2 | 5 | 洛鲁姆 |
在上表中,如果我们需要检索所有包含商品的订单的orderid、订单数量、商品价格和itemdesc ,则查询将如下所示。
SELECT o.orderid, o.qty, i.itemprice, i.itemdesc
FROM orders o
INNER JOIN items i
on o.itemid = i.itemid
结果集如下所示。
订单编号 | 数量 | 商品价格 | 项描述 |
---|---|---|---|
1 | 3 | 10 | 东西 |
2 | 4 | 5 | 洛鲁姆 |
3 | 1 | 5 | 洛鲁姆 |
从上面的结果可以看出,orderid 4 没有进入结果集,因为 orders 表中的 itemid 3 在 items 表中找不到。由于 INNER JOIN 仅返回两个表中都存在的行,因此 orderid 4 被从结果集中过滤掉。
使用外连接
到目前为止,您已经了解了如何使用内连接来匹配不同表中的行。SQL Server 通过过滤掉不满足 ON 子句谓词中表达的条件的行来构建内连接查询的结果。结果是只显示来自两个表的匹配行。使用外连接,您可以选择显示一个表中的所有行以及来自第二个表的匹配行。
以下是有关外连接的一些重要说明:
- 外连接返回一个表中的所有行以及第二个表中的匹配行。
- 如果连接无法从第二个表中找到匹配的记录,则第二个表的结果将显示为 NULL。
- 与内连接不同,在 FROM 子句中列出和连接的表的顺序很重要,因为它将决定您为连接选择 LEFT 还是 RIGHT。
以下将返回第一个表 (a) 中的所有行以及第二个表 (b) 中的匹配行。
FROM a LEFT OUTER JOIN b
on a.id = b.id
以下将返回第二个表 (b) 中的所有行以及第一个表 (a) 中的匹配行。
FROM a RIGHT OUTER JOIN b
on a.id = b.id
外连接示例
考虑上面的内连接示例中使用的订单和项目表。
假设我们需要编写一个查询来检索所有订单的 orderid、订单数量、商品价格和 itemdesc。如果订单在 items 表中没有 itemid,则应返回订单详细信息,但商品详细信息应显示为 NULL。
在这种情况下,最好使用 LEFT(外部)JOIN,因为它将返回第一个表中的所有行,并且仅返回第二个表中的所有匹配行。
查询如下。
SELECT o.orderid, o.qty, i.itemprice, i.itemdesc
FROM orders o
LEFT JOIN items i
on o.itemid = i.itemid
结果集如下所示。
订单编号 | 数量 | 商品价格 | 项描述 |
---|---|---|---|
1 | 3 | 10 | 东西 |
2 | 4 | 5 | 洛鲁姆 |
3 | 1 | 5 | 洛鲁姆 |
4 | 3 | 无效的 | 无效的 |
使用交叉连接
交叉连接查询会创建笛卡尔积,您在本指南前面已经了解过该积。
要明确创建笛卡尔积,您可以使用 CROSS JOIN 运算符。这将创建一个包含所有可能输入行组合的结果集。
当使用 CROSS JOIN 编写查询时,请记住没有执行行匹配,因此不需要 ON 子句。
考虑下面的例子。
表A
一个 |
---|
1 |
2 |
3 |
表 B
乙 |
---|
十 |
是 |
是 |
SELECT *
FROM A
CROSS JOIN B
结果是
一个 | 乙 |
---|---|
1 | 十 |
1 | 是 |
1 | 是 |
<font style="ver |
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~