天天看点

第六十章 SQL命令 JOIN(二)

文章目录

  • 第六十章 SQL命令 JOIN(二)
  • 单向外部联接
    • 外部联接语法
    • Null填充
  • 混合外部和内部连接
    • 多重连接和隐式连接的性能
  • 示例
    • CROSS JOIN 示例
    • NATURAL JOIN 示例
    • 使用ON子句的INNER JOIN示例
    • 使用USING子句的INNER JOIN示例
    • LEFT OUTER JOIN 示例
    • RIGHT OUTER JOIN 示例
    • FULL OUTER JOIN

单向外部联接

IRIS支持单向外部联接:左外部联接和右外部联接。

使用标准的

“inner”

联接时,当一个表的行链接到第二个表的行时,第一个表中找不到第二个表中对应行的行将从输出表中排除。

使用单向外联接时,即使第二个表中没有匹配项,第一个表中的所有行也会包括在输出表中。使用单向外连接,第一个表会从第二个表中取出相关信息,但不会因为第二个表中缺少匹配项而牺牲自己的行。

例如,如果查询首先列出

Table1

并创建一个左外部联接,那么它应该能够看到

Table1

中的所有行,即使它们在

Table2

中没有对应的记录。

在指定单向外联接时,在

FROM

子句中命名表的顺序非常重要。对于左外部联接,指定的第一个表是联接的源表。对于右外部联接,指定的第二个表是联接的源表。因此,

%INORDER

%STARTTABLE

优化关键字不能与

RIGHT OUTER JOIN

一起使用。以下语法相互矛盾,导致

SQLCODE-34

错误:

FROM%INORDER TABLE1 RIGHT OUTER JOIN TABLE2 ON....

IRIS支持两种表示外连接的格式:

  1. ANSI

    标准语法:

    LEFT OUTER JOIN

    RIGHT OUTER JOIN

    。SQL标准语法将外联接放在

    SELECT

    语句的

    FROM

    子句中,而不是

    WHERE

    子句中,如下例所示:
FROM tbl1 LEFT OUTER JOIN tbl2 ON (tbl1.key = tbl2.key) 
           
  1. ODBC规范外部联接扩展语法,使用转义语法

    {OJ Join-Expression}

    ,其中

    Join-Expression

    是任何ANSI标准联接语法。

单向外联接执行空值填充。这意味着,如果源表的某一行的合并列具有空值,则会为非源表中的相应字段返回空值。

左外部联接条件由以下语法表示:

A LEFT OUTER JOIN B ON A.x=B.y
           

这指定返回

A

中的每一行。对于返回的每个

A

行,如果有一个

B

行使得

A.x=B.Y

,则还将返回所有相应的B值。

如果没有

A.x=B.y

B

行,则填充空值会导致该

A

行的所有

B

值返回为空值。

例如,考虑包含患者信息的

Patient

表,其中包括一个字段

Patient

指定患者主治医生的

DocID

ID

代码。

数据库中的一些患者没有主诊医生,因此对这些患者记录“患者”。

DocID

字段为

NULL

现在,我们在

Patient

表和

Doctor

表之间执行连接,以生成一个包含患者姓名和相应医生姓名的表。

SELECT Patient.PName,Doctor.DName
   FROM Patient INNER JOIN Doctor
   ON Patient.DocID=Doctor.DocID
           

INNER JOIN

不执行空填充。

因此,如果没有相应的医生姓名,则不会返回患者姓名。

单向外联接确实执行空值填充。因此,没有相应医生名称的患者名称将为

Doctor.DName

返回

NULL

SELECT Patient.PName,Doctor.DName
   FROM Patient LEFT OUTER JOIN Doctor
   ON Patient.DocID=Doctor.DocID
           

单向外联接条件(包括必要的空值填充)在其他条件之前应用。因此,

WHERE

子句中不能由填充空值的值满足的条件(例如,

B

中字段的范围或相等条件)有效地将

A

B

的单向外联接转换为常规联接(内联接)。

例如,如果将子句

“WHERE Doctor.Age < 45”

添加到上面的两个

“Patient”

表查询中,则它们是等效的。但是,如果添加子句

“WHERE Doctor.Age < 45 OR Doctor.Age is null”

,它将保留这两个查询之间的差异。

混合外部和内部连接

IRIS支持任意顺序的混合内部连接和外部连接的所有语法。

默认情况下,查询优化器将多个连接操作按其对最优序列的最佳估计排序。

这不一定是在查询中指定的连接顺序。

可以在

FROM

子句中指定

%INORDER

%FIRSTTABLE

%STARTTABLE

查询优化选项,以显式指定表连接的顺序。

查询优化器可以执行子查询扁平化,将某些子查询转换为显式连接。

当子查询数量较少时,这将极大地提高连接性能。

当子查询的数量超过一个或两个时,子查询扁平化在某些情况下可能会略微降低性能。

FROM

%NOFLATTEN

查询优化选项,以显式指定不应该执行子查询扁平化。

只有当子查询扁平化后,查询中的连接总数不超过

15

个连接时,查询优化器才会执行子查询扁平化。

指定超过

15

个联接,如果其中一些联接是隐式联接或联接子查询,则会导致查询性能的显著下降。

示例

下面的示例显示了在表1和表2上执行

JOIN

操作的结果。

Table1

Column1 Column2
aaa bbb
ccc
xxx yyy
hhh zzz
Column3
ggg

SELECT * FROM Table1 CROSS JOIN Table2
           

SELECT * FROM Table1 NATURAL JOIN Table2
           

SELECT * FROM Table1 INNER JOIN Table2
     ON Table1.Column1=Table2.Column3
           

SELECT * FROM Table1 INNER JOIN Table2
  USING (Column1)
           

SELECT * FROM Table1 LEFT OUTER JOIN Table2
  ON Table1.Column1=Table2.Column3
           
null

SELECT * FROM Table1 RIGHT OUTER JOIN Table2
     ON Table1.Column1=Table2.Column3
           

SELECT * FROM Table1 FULL OUTER JOIN Table2
  ON Table1.Column1=Table2.Column3