层级查询子句

层级子句对表对象上的递归查询设置条件,在该表对象的行之中,存在父子依赖的层级。包括此子句的 SELECT 语句称为层级查询

必须在 SELECT 语句的 FROM 子句中指定在其上进行层级查询操作的表对象。该表对象通常是自引用表,在其中一个或多个列作为同一表中另一列(或这些列的子集)的外键约束。

层级查询对若干行进行操作,在其中一个或多个列值对应于父子关系的逻辑结构之内的节点。如果父行有多个孩子,则在同一父母的孩子行之中存在兄弟关系。例如,这些关系可能反映一个组织的部门和管理级别之内的员工与管理者之中的报告结构。

此子句支持的语法是对 SQL 的 ANSI/ISO 标准的扩展。

语法

层级子句
必须在 SELECT 语句的 FROM 子句中指定层级查询在其上操作的那些表对象。该表对象可为下列表对象中的任何一种:
  • 表或可更新的视图
  • 临时表
  • 该会话连接到的同一 GBase 8s 实例的另一数据库中的表
  • 作为查询的结果的派生的表
  • 受到基于标签的访问控制(LBAC)安全策略保护的表
  • 带有列级加密或行级加密的表
  • 任何其他表对象的同义词。
在层级查询的 FROM 子句中,不支持下列表对象:
  • 两个或多个表的连接
  • 不可更新的视图
  • 远程 GBase 8s 实例的数据库中的表
  • CREATE EXTERNAL TABLE 语句定义了的外部表
  • 序列对象。

GBase 8s 支持在层级查询的 projection 列表中的序列对象,在 WHERE 子句中,以及在表达式在 SELECT 语句中为有效的其他上下文中,但不在层级查询子句中。

在相关联的子查询和在不相关联的子查询中,层级子句是无效的。

层级查询可包括所有类型的优化程序伪指令,这些是例外:
  • 连接顺序伪指令
  • 连接方法伪指令

层级查询不支持 GBase 8s 的“并行数据库查询”(PDQ)特性。

层级子句可在表上指定递归的查询,该表的行描述父子关系的层级。
  • 该层级可为简单的层级,诸如组织的报告结构,其中每个非根的节点向该层级之内的高级的单个节点报告。 (在 GBase 8s 的 LBAC 安全特性中,TREE 类型的安全标签组件有简单的层级的逻辑结构。)
  • 层级子句可查询更复杂拓扑的数据层级,其中的节点有多对多关系,且其中的孩子节点可为其父母的祖先。要了解关于使用层级子句来查询在数据层级之内有循环的信息,请参阅 CONNECT BY 子句
重要: 层级查询对某些数据集合最为有效,其中的表内的父子依赖有简单图的逻辑拓扑。如果自引用表包括对相同列集合的多个独立的层级,或如果任何孩子行还是其父母的祖先,则请参阅 不是简单图的依赖样式
注: 层级子句与表层级无关,在一系列类型表的模式之中存在父子关系的层级。类似地,全都来自通用基础类型的一系列 DISTINCT 数据类型的层级与数据层级类似,但与层级子句无关,层级存在于数据实体之间的父子依赖中,而不是数据类型之中的关系。

特定于层级查询的 SQL 语法

除了为包含层级数据的表的递归查询指定条件的 START WITH、CONNECT BY 和 CONNECT NOCYCLE BY 关键字之外,层级查询还支持那些仅在层级查询中才有效的语法令牌,以及在没有 CONNECT BY 子句的 SELECT 语句中不可使用的语法令牌。 特定于层级查询的语法令牌包括两个运算符、三个伪列和一个内建的函数:
  • CONNECT_BY_ROOT 运算符

    此运算符可为其运算对象的根祖先返回一表达式。

  • PRIOR 运算符

    此运算符可引用从前一递归步骤返回的值(此处的“步骤”是指该递归查询的一次迭代)。

  • LEVEL 伪列

    此伪列返回一整数,指示该层级之内递归查询的哪一步骤返回了行。

  • CONNECT_BY_ISCYCLE 伪列

    此伪列可指示一行是否有一个还是其祖先的孩子。

  • CONNECT_BY_ISLEAF 伪列

    此伪列可指示一行在查询返回的行之中是否有任何的孩子。

  • SYS_CONNECT_BY_PATH 函数

    此函数可构建和返回一字符串,该字符串表示从指定的行到层级的根的路径

  • 在 ORDER BY 子句中的 SIBLINGS 关键字

    ORDER SIBLINGS BY 子句可对返回的每个级别的同一父母的兄弟行进行排序。

伪列是在特定的上下文中 SQL 解析器可识别的内建的标识符,共享同一命名空间作为列和变量。通常在 SELECT 语句的 Projection 子句中指定这些伪列和 SYS_CONNECT_BY_PATH 函数,但可在层级子句中指定 LEVEL 伪列和 PRIOR 运算符。

要获取仅支持层级查询的这些令牌的语法和语义的详细信息,请参阅 在 CONNECT BY 子句中的条件ORDER SIBLINGS BY 子句

层级查询概述

按下列次序处理包括层级子句的 SELECT 语句的子句:
  1. FROM 子句(仅对于当前数据库中的单个表对象)
  2. Hierarchical 子句
  3. WHERE 子句(无连接断言)
  4. GROUP BY 子句
  5. HAVING 子句
  6. Projection 子句
  7. ORDER BY 子句

ORDER BY 子句的 ORDER BY SIBLING 选项可对同一父母的孩子行的集合进行排序。

包括层级子句的子查询按部分的顺序返回中间结果集,在此,特定层级的迭代(n+1)中产生的行紧跟在产生它们的迭代(n)中的行之后。然而,ORDER BY 子句、GROUP BY 或 HAVING 子句,或在 Projection 子句中指定的 DISTINCT 或 UNIQUE 关键字会销毁那部分的顺序。

层级子句跟在 SELECT 语句子句的词汇序列中的 WHERE 子句之后,但在该层级子句的结果上处理 WHERE 子句断言。如果 SELECT 语句包括层级子句,则 WHERE 子句不可指定连接子句,但在 FROM 子句中指定的表对象可作为连接一个或多个表的查询的结果集。

任何包括层级查询子句的 SELECT 语句都称为层级查询,在 FROM 子句指定的表上执行查询的递归序列:
  1. 可选的 START WITH 子句可指定条件。返回任何满足此条件的行作为该层级查询的第一个中间结果集。
  2. 下一步骤将在 CONNECT BY 子句中指定的条件应用到表。返回任何满足那个条件的行作为第二个中间结果集。
  3. 下一步骤将 CONNECT BY 条件应用到表。返回的任何行构成第三个中间结果集。
  4. CONNECT BY 子句递归地运行查询来产生连续的中间结果集,直到迭代产生空结果集为止。
  5. 然后,层级 SELECT 语句组合前面的递归步骤的所有中间结果集,产生该层级子句的最终结果集。
  6. 然后,将 WHERE 子句的断言应用到该层级子句检索了的这个行集合,然后按罗列的顺序应用 SELECT 语句的剩余的子句。

在 START WITH 和 CONNECT BY 子句返回所有中间的结果集之后,您可使用 ORDER SIBLINGS BY 子句来对该层级之内的每个级别的有相同的父母的兄弟行进行排序。要获取更多信息,请参阅 ORDER SIBLINGS BY 子句

您可使用来自 SET EXPLAIN 语句的输出来查看层级查询的执行路径。

层级子句提供一种有效的替代机制,使用节点数据库扩展来从层级数据集检索信息

层级数据集的示例

在接下来的几个主题中,那些展示层级查询的 SQL 代码示例是基于下列 employee 表中的层级数据,其行包含关于在组织的层级之内的员工的信息。mgrid 列展示员工向其汇报的管理者的员工标识符(empid):

CREATE TABLE employee(
        empid  INTEGER NOT NULL PRIMARY KEY,
        name   VARCHAR(10),
        salary DECIMAL(9, 2),
        mgrid  INTEGER
        );

employee 表中 17 行的数据值如下。

INSERT INTO employee VALUES  ( 1, 'Jones',    30000, 10);
        INSERT INTO employee VALUES  ( 2, 'Hall',     35000, 10);
        INSERT INTO employee VALUES  ( 3, 'Kim',      40000, 10);
        INSERT INTO employee VALUES  ( 4, 'Lindsay',  38000, 10);
        INSERT INTO employee VALUES  ( 5, 'McKeough', 42000, 11);
        INSERT INTO employee VALUES  ( 6, 'Barnes',   41000, 11);
        INSERT INTO employee VALUES  ( 7, 'O''Neil',  36000, 12);
        INSERT INTO employee VALUES  ( 8, 'Smith',    34000, 12);
        INSERT INTO employee VALUES  ( 9, 'Shoeman',  33000, 12);
        INSERT INTO employee VALUES  (10, 'Monroe',   50000, 15);
        INSERT INTO employee VALUES  (11, 'Zander',   52000, 16);
        INSERT INTO employee VALUES  (12, 'Henry',    51000, 16);
        INSERT INTO employee VALUES  (13, 'Aaron',    54000, 15);
        INSERT INTO employee VALUES  (14, 'Scott',    53000, 16);
        INSERT INTO employee VALUES  (15, 'Mills',    70000, 17);
        INSERT INTO employee VALUES  (16, 'Goyal',    80000, 17);
        INSERT INTO employee VALUES  (17, 'Urbassek', 95000, NULL);

每一 empidmgrid 值对表达引用的关系,带有适当的 CONNECT BY 条件的查询的递归迭代可正确地组装成层级。

在此,最后一行中 mgrid 列中的 NULL 值展示其 empid 值为 17 的员工 Urbassek 是此报告层级的根节点。

下图展示 employee 表数据的报告层级(以展示 empid 值的节点)的四个级别:

图: 在报告层级中的元素的关系


START ALTEXT: 图示员工的层级(通过展现他们的数值员工标识符来表现)以及每一员工(root 除外)向其报告的管理者。END ALTTEXT
1 请参阅 START WITH 子句
2 请参阅 CONNECT BY 子句