【问题标题】:Oracle - using connect by prior in Hierarchical Queries and put them into rowsOracle - 在分层查询中使用先连接并将它们放入行中
【发布时间】:2021-11-05 01:03:49
【问题描述】:

我是 Oracle 的新手,我将在实现平面表而不是分层表之前使用 connect by。但我有点困惑。我的桌子是这样的: 员工表:

empID empName managerID
100 Sara 110
101 Ben 111
102 Alex 110
110 Ross 111
111 Mon NULL

我要这样改变表格(输出):

emp empName subBoss subBossName Boss BossName
100 Sara 110 Ross 111 Mon
101 Ben 111 Mon NULL NULL
102 Alex 110 Ross 111 Mon
110 Ross 111 Mon NULL NULL
111 Mon NULL NULL NULL NULL

【问题讨论】:

    标签: sql oracle connect-by


    【解决方案1】:

    MDO 答案的简短版本是 -

    WITH DATA AS (SELECT 100 AS empID, 'Sara' AS empName, 110 AS managerID FROM DUAL UNION ALL
                  SELECT 101, 'Ben', 111 FROM DUAL UNION ALL
                  SELECT 102, 'Alex', 110 FROM DUAL UNION ALL
                  SELECT 110, 'Ross', 111 FROM DUAL UNION ALL
                  SELECT 111, 'Mon', NULL FROM DUAL)
     SELECT empID emp, empName, prior empID subBoss, prior empName subBossName
        , prior t.managerID Boss
        ,CASE WHEN PRIOR t.managerID IS NOT NULL THEN CONNECT_BY_ROOT(t.empName) END AS BossName
      FROM DATA T
     START WITH managerID IS NULL
    CONNECT BY PRIOR empID = managerID
      ORDER BY 1;
    

    Demo.

    【讨论】:

    • 如果层次结构有 4 个(或更多)级别,那么这将从层次结构的不同级别 db<>fiddle 获取 boss 的值 idname
    【解决方案2】:

    您也可以为此使用 connect by 子句。

    select empID, empName
      , subBoss, subBossName
      , (select boss.empID from YourTable boss where boss.empID = subBossManagerID) Boss
      , (select boss.empName from YourTable boss where boss.empID = subBossManagerID) BossName
    from (
      select empID, empName
        , prior empID subBoss, prior empName subBossName
        , prior t.managerID subBossManagerID
      from YourTable t
      start with managerID is null
      connect by prior empID = managerID
    )
    order by 1
    ;
    

    test here

    【讨论】:

    • 很高兴看到我能提供帮助。
    【解决方案3】:

    您可以为此使用递归子查询分解子句:

    WITH hierarchy (empID, empName, subBoss, subBossName, boss, bossName, depth, managerId) AS (
      SELECT empID,
             empName,
             CAST(NULL AS NUMBER),
             CAST(NULL AS VARCHAR2(20)),
             CAST(NULL AS NUMBER),
             CAST(NULL AS VARCHAR2(20)),
             1,
             managerID
      FROM   empTbl
    UNION ALL
      SELECT h.empID,
             h.empName,
             CASE h.depth
             WHEN 1 THEN e.empID
             ELSE h.subBoss
             END,
             CASE h.depth
             WHEN 1 THEN e.empName
             ELSE h.subBossName
             END,
             CASE h.depth
             WHEN 2 THEN e.empID
             ELSE h.boss
             END,
             CASE h.depth
             WHEN 2 THEN e.empName
             ELSE h.bossName
             END,
             h.depth + 1,
             e.managerID
      FROM   hierarchy h
             LEFT OUTER JOIN empTbl e
             ON (h.managerID = e.empID)
      WHERE  depth < 3
    )
    CYCLE empID, depth SET is_cycle TO 1 DEFAULT 0
    SELECT empID, empName, subBoss, subBossName, boss, bossName
    FROM   hierarchy
    WHERE  depth = 3;
    

    或者,您可以使用分层查询和数据透视:

    SELECT emp_id AS empID,
           emp_name AS empName,
           subboss_id AS subbossid,
           subboss_name AS subbossname,
           boss_id AS bossid,
           boss_name AS bossname
    FROM   (
      SELECT CONNECT_BY_ROOT(empID) AS root_empid,
             empID,
             empName,
             LEVEL AS depth
      FROM   empTbl
      WHERE  LEVEL <= 3
      CONNECT BY PRIOR managerID = empID
    )
    PIVOT (
      MAX(empID) AS id,
      MAX(empName) AS name
      FOR depth IN (
        1 AS emp,
        2 AS subBoss,
        3 AS boss
      )
    )
    ORDER BY empid;
    

    其中,对于样本数据:

    CREATE TABLE empTbl (empID, empName, managerID) AS
    SELECT 100, 'Sara', 110 FROM DUAL UNION ALL
    SELECT 101, 'Ben',  111 FROM DUAL UNION ALL
    SELECT 102, 'Alex', 110 FROM DUAL UNION ALL
    SELECT 110, 'Ross', 111 FROM DUAL UNION ALL
    SELECT 111, 'Mon',  NULL FROM DUAL;
    

    两个输出:

    EMPID EMPNAME SUBBOSS SUBBOSSNAME BOSS BOSSNAME
    100 Sara 110 Ross 111 Mon
    102 Alex 110 Ross 111 Mon
    101 Ben 111 Mon
    110 Ross 111 Mon
    111 Mon

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2020-10-10
      • 1970-01-01
      • 2019-10-07
      • 2020-05-08
      • 1970-01-01
      • 2022-01-09
      相关资源
      最近更新 更多