上一篇 | 下一篇

Terry Purcell 谈外连接(第二部分)

发布: 2008-7-01 13:40 | 作者: admin | 来源: | 查看: 0次

Terry Purcell 谈外连接(第二部分)

热 荐

【字体:小 大】

Terry Purcell 谈外连接(第二部分)

作者:- 文章来源:- 点击数:1183 更新时间:2006-4-22

Terry Purcell

高级顾问, Yevich, Lawson & Associates

2002 年 1 月 在系列文章(两篇)的这一篇(第二篇)中,Terry Purcell(DB2 金牌顾问)提供更多的建议,这些建议关于在外连接中编写谓词代码(包括在替换 NULL 的表上编写谓词代码)来确保正确的结果。

引言

这是我的专题中的第二部分,在该专题中我想让您更加容易地理解和使用 SQL 语言强大的外连接功能。

第一部分提供了内连接和外连接之间简单的比较,并且也介绍了在外连接操作中用来说明表的新术语。最终,我论述了不同的谓词类型以及在哪个阶段 DB2® 可以应用它们。

在这个部分,我将提供在替换 NULL(NULL-supplying)的表上编写谓词的背景、DB2 可以如何简化查询来改善性能以及要确保获得期望的结果所能采取的步骤。

左外连接和右外连接替换 NULL 的表谓词

外连接简化 保留 NULL 连接前(before-join)谓词

外连接简化

回顾我在 第一部分中介绍的一些术语: 保留行(preserved row)表是为连接操作中不匹配的行保留行的表。 替换 NULL的表是为连接中不匹配的行提供 NULL 行的表。

然而,应用于保留行表的 WHERE 子句谓词的最重要的属性是 DB2 可以在连接之前或之后应用谓词;应用于替换 NULL 的表的 WHERE 子句谓词的效果却非常不同,因为如果该谓词抵消了由外连接引入的 NULL,那么它使 DB2 简化连接。

要说明我说的这些是什么意思,请参见 图 13,该图展示了引用替换 NULL 的表的 WHERE 子句谓词的示例。

对一个要限定的行,WHERE 子句谓词的计算值必须为 TRUE。如果在连接中出现不匹配的行,那么来自替换 NULL 的表的列是 NULL。当 DB2 将 WHERE 子句谓词 D.DEPTNAME NOT LIKE "%CENTER%" 与 NULL 进行比较时,其结果既不是 TRUE 也不是 FALSE,而是 UNKNOWN。因为该行的计算值不是 TRUE,所以不返回该行。因而,左外连接(left outer join)提供的 NULL 被 WHERE 子句谓词抵消了。这使 DB2 确定左外连接是不必要的,并使得查询被重写为一个内连接,该内连接可能是或者可能不是您在编写该查询时想要的。

DB2 将左外连接重写为内连接的好处是可以改善性能。应用到表 D 的谓词现在可以应用在连接之前(而不是之后),因为该谓词现在引用一个不替换 NULL 的表。保留行和替换 NULL 对于内连接是不相关的术语;假定在连接中将不返回不匹配行,即,所有表都是不替换 NULL 的。

保留 NULL

如果该外连接简化没有产生您想要的结果 - 即,您要求返回 NULL(或可选)行 - 那么使用 OR D.DEPTNAME IS NULL 来保留在答案集中的 NULL。

在 图 14中展示了这样的一个示例。

DB2 必须将 WHERE 子句谓词应用在连接之后,因为直到连接之后才知道行是匹配的(因而应用谓词的第一部分 - D.DEPTNAME NOT LIKE "%CENTER%" )还是不匹配的(因而应用谓词的第二部分 - OR D.DEPTNAME IS NULL )。

连接前谓词

如果您选择编写 WHERE 子句谓词,它被 DB2 在连接 之前应用到替换 NULL 的表上,那么会发生什么?

如果您这样做,那么没有 WHERE 子句谓词来限制保留行表上或最终结果中的行。您仅限制了来自替换 NULL 的表的行。 图 15展示了这样的结果。

图 16展示如果您将连接前谓词重新编写为一个 ON 子句谓词,那么返回相同的结果。

字号: | 推荐给好友

31/3123>

评分:0

我来说两句