簡體   English   中英

Oracle - 在分層查詢中使用先連接並將它們放入行中

[英]Oracle - using connect by prior in Hierarchical Queries and put them into rows

我是 Oracle 的新手,我將在實現平面表而不是分層表之前使用 connect by。 但我有點困惑。 我的表是這樣的:empTabl:

員工編號 員工姓名 經理ID
100 薩拉 110
101 111
102 亞歷克斯 110
110 羅斯 111
111 星期一 NULL

我將像這樣更改表格(輸出):

雇員 員工姓名 副老板 subBossName 老板 老板姓名
100 薩拉 110 羅斯 111 星期一
101 111 星期一 NULL NULL
102 亞歷克斯 110 羅斯 111 星期一
110 羅斯 111 星期一 NULL NULL
111 星期一 NULL NULL NULL NULL

您可以為此使用遞歸子查詢因式分解子句:

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;

或者,您可以使用分層查詢和 pivot:

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;

output:

EMPID 企業名稱 副總裁 副老板名 老板 老板名
100 薩拉 110 羅斯 111 星期一
102 亞歷克斯 110 羅斯 111 星期一
101 111 星期一
110 羅斯 111 星期一
111 星期一

db<> 在這里擺弄

您也可以為此目的使用 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
;

在這里測試

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;

演示。

由於使用 root 連接,Ankit Bajpai 的回答在 4 級之后為經理提供了錯誤的名稱。 通過小通知,此查詢給出最短答案

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)
, b as( SELECT p.empID , p.empName, p.managerID, m.empName as managerName  FROM DATA p left join data m
   on ( p.managerID=m.empID))
 SELECT empID emp, empName, prior empID subBoss, prior empName subBossName
    , prior managerID Boss, prior managerName BossNAme
  FROM b
 START WITH managerID IS NULL
CONNECT BY PRIOR empID = managerID
  ORDER BY 1;

小提琴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM