文章目录
- 第六十章 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支持两种表示外连接的格式:
-
标准语法:ANSI
和LEFT OUTER JOIN
。SQL标准语法将外联接放在RIGHT OUTER JOIN
语句的SELECT
子句中,而不是FROM
子句中,如下例所示:WHERE
FROM tbl1 LEFT OUTER JOIN tbl2 ON (tbl1.key = tbl2.key)
- ODBC规范外部联接扩展语法,使用转义语法
,其中{OJ Join-Expression}
是任何ANSI标准联接语法。Join-Expression
单向外联接执行空值填充。这意味着,如果源表的某一行的合并列具有空值,则会为非源表中的相应字段返回空值。
左外部联接条件由以下语法表示:
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