SQL命令 JOIN(一)
基于两个表中的数据创建表的SELECT
子句。
大纲
代码语言:javascript复制table1 [[AS] t-alias1] CROSS JOIN table2 [[AS] t-alias2] |
table1 [[AS] t-alias1] , table2 [[AS] t-alias2]
table1 [[AS] t-alias1]
NATURAL [INNER] JOIN |
NATURAL LEFT [OUTER] JOIN |
NATURAL RIGHT [OUTER] JOIN |
table2 [[AS] t-alias2]
table1 [[AS] t-alias1]
[INNER] JOIN |
LEFT [OUTER] JOIN |
RIGHT [OUTER] JOIN |
FULL [OUTER] JOIN
table2 [[AS] t-alias2]
ON condition-expression
table1 [[AS] t-alias1]
[INNER] JOIN |
LEFT [OUTER] JOIN |
RIGHT [OUTER] JOIN |
table2 [[AS] t-alias2]
USING (identifier-commalist)
(上述联接语法用于SELECT
语句FROM
子句。可以在其他SELECT
语句子句中使用其他联接语法。)
描述
联接是将两个表组合在一起以生成联接表的操作,可以选择遵守一个或多个限制条件。新表的每一行都必须满足限制条件。联接提供了将一个表中的数据与另一个表中的数据链接起来的方法,并且经常用于定义报表和查询。
有几种表示联接的语法形式。首选形式是在SELECT
语句中指定显式联接表达式作为FROM
子句的一部分。FROM
子句联接表达式可以包含多个联接。
注意: SQL还支持在SELECT
语句SELECT-ITEM
列表、WHERE
子句、ORDER BY
子句和其他地方使用箭头语法(–>
)的隐式联接。指定隐式联接以执行表与另一个表中的字段的左外联接;指定显式联接以联接两个表。这种隐式联接语法可以很好地替代显式联接语法,或者与显式联接语法一起出现在同一查询中。但是,在组合箭头语法和显式连接语法方面有一些重要的限制。这些限制如下所述。
IRIS使用复杂的优化算法来最大化连接操作的性能。它不一定按照表的指定顺序联接表。相反,SQL
优化器根据每个表的Tune Table
数据(以及其他因素)确定表连接顺序。因此,在复杂SQL
查询中使用表之前,必须先针对表运行调优表,这一点很重要。
在大多数情况下,SQL
优化器策略提供最佳结果。但是, IRIS还提供联接优化关键字,如%FIRSTTABLE
、%INORDER
和%FULL
,可以在FROM
关键字之后立即使用这些关键字来覆盖特定查询的默认优化策略。
JOIN 定义
IRIS支持多种不同的连接语法形式。但是,这许多公式涉及以下五种类型的联接。
ANSI连接语法 | 句法上的等价于 |
---|---|
CROSS JOIN | 与符号表示相同:FROM子句中的Table1、Table2(用逗号分隔的表列表)。 |
INNER JOIN | 与JOIN相同。符号表示:“=”(在WHERE子句中)。 |
LEFT OUTER JOIN | 与左连接相同。箭头语法(->)还执行左外部联接。 |
RIGHT OUTER JOIN | 与右连接相同。 |
FULL OUTER JOIN | 与FULL JOIN相同。 |
除非另有说明,否则所有连接语法都在FROM
子句中指定。
- 交叉连接是将第一个表的每一行与第二个表的每一行交叉的连接。
这将产生一个笛卡尔积,即一个具有大量数据重复的、逻辑上全面的大型表。
通常这种连接是通过在
FROM
子句中提供一个逗号分隔的表列表来执行的,然后使用WHERE
子句来指定限制性条件。%INORDER
或%STARTTABLE
优化关键字不能用于交叉连接。 尝试这样做会导致SQLCODE -34
错误。 -
INNER JOIN
是将第一个表的行与第二个表的行连接起来的连接,不包括在第一个表中没有在第二个表中找到相应行的任何行。 - 左
OUTER JOIN
和右OUTER JOIN
在大多数方面功能相同(语法相反),因此经常统称为单向外部连接。 单向外部连接是将第一个(源)表的行与第二个表的行链接在一起的连接,包括第一个表的所有行,即使第二个表中没有匹配。 这将导致第一个(源)表的某些字段可能与NULL
数据配对。 - 在指定单向外部连接时,在
FROM
子句中命名表的顺序非常重要。 对于LEFT OUTER JOIN
,指定的第一个表是该连接的源表。 对于RIGHT OUTER JOIN
,指定的第二个表是连接的源表。 -
FULL OUTER JOIN
是将在两个表上执行左OUTER JOIN
和右OUTER JOIN
的结果组合在一起的连接。 它包括在第一个表或第二个表中找到的所有行,并在两边的缺失匹配中填充null
。
CROSS JOIN 注意事项
显式使用JOIN
关键字比使用逗号语法指定交叉连接具有更高的优先级。
IRIS将t1,t2 JOIN t3
解释为t1,(t2 JOIN t3)
。
不能执行涉及本地表和通过ODBC或JDBC网关连接链接的外部表的交叉连接。
例如,FROM Sample.Person,Mylink.Person
。
尝试这样做的结果是SQLCODE -161:
“对SQL连接的引用必须构成整个子查询”。
要执行此交叉连接,必须将链接表指定为子查询。
例如,FROM Sample。 Person,(SELECT * FROM Mylink.Person)
。
自然连接
NATURAL JOIN
是以NATURAL
关键字为前缀的INNER JOIN
、LEFT OUTER JOIN
或RIGHT OUTER JOIN
。
在连接前加上单词NATURAL
,说明正在连接具有相同名称的两个表的所有列。
由于NATURAL
连接对具有相同名称的所有列自动执行相等条件,因此不可能指定on
子句或USING
子句。
尝试这样做会导致SQLCODE -25
错误。
对于NATURAL
连接的两个操作数,只支持简单的基表引用(不支持视图或子查询)。
只能将NATURAL
连接指定为连接表达式中的第一个连接。
NATURAL
连接不会合并名称相同的列。
FULL JOIN
不能以NATURAL
关键字作为前缀。
尝试这样做会导致SQLCODE -94
错误。
ON 子句
内连接、左外连接、右外连接或全外连接都可以有ON
子句。
ON
子句包含一个或多个条件表达式,用于限制连接操作返回的值。
带有ON
子句的连接可以在连接表达式中的任何位置指定。
带有ON
子句的连接可以为连接的任一操作数指定表、视图或子查询。
ON
子句由一个或多个条件表达式谓词组成。
其中包括SQL支持的大多数谓词。
但是,不能使用FOR SOME %ELEMENT
集合谓词来限制连接操作。
可以使用AND
、OR
和NOT
逻辑操作符关联多个条件表达式。
AND
优先于OR
。
括号可以用来嵌套和分组条件表达式。
除非用括号分组,否则使用相同逻辑运算符的谓词严格按照从左到右的顺序执行。
ON
子句有以下限制:
- 带有
ON
子句的连接只能使用ANSI
连接关键字语法。 - 带有
ON
子句的连接不能使用NATURAL
关键字前缀。 这将导致SQLCODE -25
错误。 - 带有
ON
子句的连接不能接受USING
子句。 这将导致SQLCODE -25
错误。 -
ON
子句不能包含箭头语法(- >
)。 这将导致SQLCODE -67
错误。 -
ON
子句只能引用ANSI
关键字JOIN
操作中显式指定的表。 在FROM
子句中指定的其他表不能在ON
子句中引用。 这将导致SQLCODE -23
错误。 -
ON
子句只能引用位于JOIN
操作数中的列。 多个连接中的语法优先级可能会导致ON子句失败。 例如,查询SELECT * FROM t1,t2 JOIN t3 ON t1.p1=t3.p3
失败,因为t1
和t3
不是join
的操作数;t1
连接t2 JOIN t3
的结果集。SELECT * FROM t1 CROSS JOIN t2 JOIN t3 ON t1.p1=t3。 p3
或者SELECT * FROM t2,t1 JOIN t3 ON t1.p1=t3.p3
。
SELECT *
FROM Table1
LEFT JOIN Table2 ON Table1.k = Table2.k
LEFT JOIN Table3 ON COALESCE(Table1.k,Table2.k) = Table3.k
使用FULL OUTER JOIN
或RIGHT OUTER JOIN
的类似示例也有这个限制。
ON子句索引
为了获得最佳性能,ON
子句中引用的字段应该(在大多数情况下)具有关联索引。
ON
子句可以使用只满足某些连接条件的现有索引。
在多个字段上指定条件的ON
子句可以使用只包含这些字段子集的索引作为下标,以部分满足连接;
IRIS将直接从表中测试其余字段的连接条件。
ON
子句中引用的字段的排序规则类型应该与它在相应索引中的排序规则类型匹配。
排序规则类型不匹配可能导致索引不被使用。
但是,如果连接条件位于%EXACT
字段值上,但只有排序字段值上的索引可用, IRIS可以使用该索引来限制要检查的行以获取准确值。
在一些非常特殊的情况下,可能希望通过在ON
子句条件前面加上%NOINDEX
关键字来防止索引的使用。
USING 子句
INNER JOIN
、LEFT OUTER JOIN
或RIGHT OUTER JOIN
可以有USING
子句。
对于使用USING
子句的连接的操作数,只支持简单的基表引用(不支持视图或子查询)。
带有USING
子句的连接只能指定为连接表达式中的第一个连接。
使用USING
子句的连接不能使用NATURAL
关键字前缀或ON子句。
USING
子句列出一个或多个列名,列名由逗号分隔,用括号括起来。
括号是必需的。
只允许显式的列名;
%ID
不允许。
重复的列名被忽略。
USING
子句不会合并名称相同的列。
USING
子句是表示ON
子句中表达的相等条件的一种简单方式。因此:t1 INNER JOIN t2 USING (a,b)
等价于t1.a=t2.a
和t1.b=t2.b
上的T1
内连接T2