FROM 子句
FROM 子句指定要应用查询的对象的集合。每个集合由抽象模式名 (ASN) 或用于标识关系的路径表达式指定。将对每个集合定义一个标识变量。
从概念上讲,查询的语义将首先构成元组的临时集合 R,其元素由集合中所有可能的对象组合组成。此集合受任何路径关系和 JOIN 运算强加的约束进行限制。JOIN 可以是内连接,也可以是外连接。
标识变量将绑定至元组的元素。在构成临时集合之后,WHERE 子句的搜索条件将应用于 R,并且产生新的临时集合 R1。ORDER BY、GROUP BY、HAVING 和 SELECT 子句应用于 R1 以生成最终结果。
from_clause::=FROM identification_variable_declaration [, {identification_variable_declaration |
collection_member_declaration } ]*
identification_variable_declaration::= range_variable_declaration [join]*
join := [ { LEFT [OUTER] | INNER }] JOIN {collection_valued_path_expression | single_valued_path_expression}
[AS] identifier
示例:连接集合
DeptBean 包含记录 10、20 和 30。EmpBean 包含与部门 10 相关的记录 1、2 和 3 以及与部门 20 相关的记录 4 和 5。部门 30 没有相关的职员。
SELECT d FROM DeptBean AS d, EmpBean AS e
WHERE d.name = e.name
逗号语法执行内连接,从而生成所有可能的组合。在此示例中,R 将由 15 个元组组成(3 个部门 x 5 个职员)。如果任一集合是空的,那么 R 也是空的。关键字 AS 是可选的。
此示例显示与自身进行连接的集合。
SELECT d FROM DeptBean AS d, DeptBean AS d1
R
将由 9 个元组组成(3 个部门 x 3 个部门)。示例:关系连接
集合可以是基于先前所声明标识的关系,如在以下代码中
SELECT e FROM DeptBean AS d , IN (d.emps) AS e
R 将包含 5 个元组。部门 30 不会出现在 R 中,这是因为它不包含任何职员。部门
10 将出现在 3 个元组中,而部门 20 将出现在 2 个元组中。IN
仅指多值关系。以下代码无效:SELECT m FROM EmpBean e, IN( e.dept.mgr) as m INVALID
当连接关系时,还可使用备用语法
INNER JOIN(关键字 INNER 是可选的),如此处所示。
SELECT e FROM DeptBean AS d INNER JOIN d.emps AS e
ASN 声明(先前查询中的 d)可后跟一个或多个连接子句。JOIN
关键字后的关系必须与 ASN 声明(直接或间接)相关。与 IN
子句的情况不同,连接子句中使用的关系可以是单值的,也可以是多值的。此查询具有的语义与以下查询具有的语义相同SELECT e FROM DeptBean AS d , IN (d.emps) AS e
可将多个连接一起使用。
SELECT m FROM EmpBean e JOIN e.dept d JOIN d.mgr m
这等价于 SELECT m FROM EmpBean e JOIN e.dept.mgr m
示例:OUTER JOIN
OUTER JOIN 会产生临时集合,该集合包含左操作数和右操作数的组合,受关系约束限制,这样,左操作数始终出现在
R 中。在该示例中,外连接会产生临时集合 R,该集合包含部门 30,即使集合 d.emps 为空,也会如此。该元组包含部门 30 和 NULL 值。在查询中引用 e
会产生空值。
SELECT e FROM DeptBean AS d LEFT OUTER JOIN d.emps AS e
关键字 OUTER
是可选的,如此处所示。
SELECT e FROM DeptBean AS d LEFT JOIN d.emps AS e
还可使用
INNER JOIN 和 OUTER JOIN 的组合。
SELECT m FROM EmpBean e JOIN e.dept d LEFT JOIN d.mgr m