具有递归 CTE 的 Oracle CONNECT BY 功能

Oracle 的 CONNECT BY 功能提供了许多有用且非常重要的功能,这些功能在使用 SQL 标准递归 CTE 时不是内置的。此示例使用 SQL Server 语法复制这些功能(为了完整性,添加了一些功能)。对于 Oracle 开发人员来说,在其他数据库的分层查询中发现许多缺少的功能是最有用的,但它也可以用来展示分层查询通常可以做些什么。

  WITH tbl AS (
       SELECT id, name, parent_id
         FROM mytable)
     , tbl_hierarchy AS (
       /* Anchor */
       SELECT 1 AS "LEVEL"
            --, 1 AS CONNECT_BY_ISROOT
            --, 0 AS CONNECT_BY_ISBRANCH
            , CASE WHEN t.id IN (SELECT parent_id FROM tbl) THEN 0 ELSE 1 END AS CONNECT_BY_ISLEAF
            , 0 AS CONNECT_BY_ISCYCLE
            , '/' + CAST(t.id   AS VARCHAR(MAX)) + '/' AS SYS_CONNECT_BY_PATH_id
            , '/' + CAST(t.name AS VARCHAR(MAX)) + '/' AS SYS_CONNECT_BY_PATH_name
            , t.id AS root_id
            , t.*
         FROM tbl t
        WHERE t.parent_id IS NULL                            -- START WITH parent_id IS NULL
       UNION ALL
       /* Recursive */
       SELECT th."LEVEL" + 1 AS "LEVEL"
            --, 0 AS CONNECT_BY_ISROOT
            --, CASE WHEN t.id IN (SELECT parent_id FROM tbl) THEN 1 ELSE 0 END AS CONNECT_BY_ISBRANCH
            , CASE WHEN t.id IN (SELECT parent_id FROM tbl) THEN 0 ELSE 1 END AS CONNECT_BY_ISLEAF
            , CASE WHEN th.SYS_CONNECT_BY_PATH_id LIKE '%/' + CAST(t.id AS VARCHAR(MAX)) + '/%' THEN 1 ELSE 0 END AS CONNECT_BY_ISCYCLE
            , th.SYS_CONNECT_BY_PATH_id   + CAST(t.id   AS VARCHAR(MAX)) + '/' AS SYS_CONNECT_BY_PATH_id
            , th.SYS_CONNECT_BY_PATH_name + CAST(t.name AS VARCHAR(MAX)) + '/' AS SYS_CONNECT_BY_PATH_name
            , th.root_id
            , t.*
         FROM tbl t
              JOIN tbl_hierarchy th ON (th.id = t.parent_id) -- CONNECT BY PRIOR id = parent_id
        WHERE th.CONNECT_BY_ISCYCLE = 0)                     -- NOCYCLE
SELECT th.*
     --, REPLICATE(' ', (th."LEVEL" - 1) * 3) + th.name AS tbl_hierarchy
  FROM tbl_hierarchy th
       JOIN tbl CONNECT_BY_ROOT ON (CONNECT_BY_ROOT.id = th.root_id)
 ORDER BY th.SYS_CONNECT_BY_PATH_name;                       -- ORDER SIBLINGS BY name

上面演示了 CONNECT BY 功能,并附有说明:

  • 条款
    • CONNECT BY:指定定义层次结构的关系。
    • START WITH:指定根节点。
    • 订购 SIBLINGS BY:正确订购结果。
  • 参数
    • NOCYCLE:检测到循环时停止处理分支。有效层次结构是有向非循环图,循环引用违反此构造。
  • 运算符
    • PRIOR:从节点的父节点获取数据。
    • CONNECT_BY_ROOT:从节点的根获取数据。
  • 伪列
    • LEVEL:表示节点与其根的距离。
    • CONNECT_BY_ISLEAF:表示没有子节点的节点。
    • CONNECT_BY_ISCYCLE:表示具有循环引用的节点。
  • 功能
    • SYS_CONNECT_BY_PATH:返回从其根节点到该节点的路径的展平/连接表示。