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 d1R
将由 9 个元组组成(3 个部门 x 3 个部门)。示例:关系连接
集合可以是基于先前所声明标识的关系,如在以下代码中
SELECT e FROM DeptBean AS d , IN (d.emps) AS eR 将包含 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 中。 在该示例中,外连接生成一个包含部门 30 的临时集合 R,尽管该集合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