是否可以使用oracle函数为维度创建层次结构?
请参阅下面的示例了解组织级别层次结构。
+-----+------+---------+
| EMP | LEAD | MANAGER |
+-----+------+---------+
| E1 | L1 | M1 |
| E3 | L3 | M1 |
| E2 | L2 | M1 |
+-----+------+---------+
但数据的最终表示应该是( sample ):
+-----+----------+----------+----------+
| EMP | LVL_1_ID | LVL_2_ID | LVL_3_ID |
+-----+----------+----------+----------+
| M1 | | | M1 |
| L1 | | L1 | M1 |
| L2 | | L2 | M1 |
| E1 | E1 | L1 | M1 |
| E2 | E2 | L2 | M1 |
| E3 | E3 | L3 | M1 |
| L3 | | L3 | M1 |
+-----+----------+----------+----------+
EMP_ID列将包含所有员工的条目(包括潜在客户和经理)。
代码:
SELECT employee AS emp_id,
employee AS Level_1_id,
LEAD AS level_2_id,
Manager AS Level_3_id
FROM temp_emp
UNION
SELECT LEAD AS emp_id,
NULL AS Level_1_id,
LEAD AS level_2_id,
Manager AS Level_3_id
FROM temp_emp
UNION
SELECT manager AS emp_id,
NULL AS Level_1_id,
NULL AS level_2_id,
Manager AS Level_3_id
FROM temp_emp ;
根据评论,我在以下数据集中尝试了“Connect By”子句:
+-----+---------+
| EMP | MANAGER |
+-----+---------+
| E1 | L1 |
| E2 | L1 |
| E3 | L2 |
| L1 | M1 |
| L2 | M1 |
| M1 | |
+-----+---------+
获得以下结果:
+-----+----------+----------+-----------+
| EMP | LVL_1_ID | LVL_2_ID | LVL_3_ID |
+-----+----------+----------+-----------+
| M1 | | |M1 |
| L1 | |L1 | |
| L2 | |L2 | |
| E1 |E1 | | |
| E2 |E2 | | |
| E3 |E3 | | |
+-----+----------+----------+-----------+
用于获取此代码的代码(仍然不是必需的答案):
SELECT * FROM (
SELECT EMP AS CH,EMP AS emp,LEVEL AS LVL
FROM TEMP_EMP
START WITH MANAGER IS NULL
CONNECT BY PRIOR EMP = MANAGER)
PIVOT (MAX(CH) FOR (LVL) IN ('3' AS LVL_1_ID,'2' AS LVL_2_ID,'1' AS LVL_3_ID));
预期结果:
+-----+----------+----------+----------+
| EMP | LVL_1_ID | LVL_2_ID | LVL_3_ID |
+-----+----------+----------+----------+
| M1 | | | M1 |
| L1 | | L1 | M1 |
| L2 | | L2 | M1 |
| E1 | E1 | L1 | M1 |
| E2 | E2 | L1 | M1 |
| E3 | E3 | L2 | M1 |
+-----+----------+----------+----------+
答案 0 :(得分:1)
以下代码将提供所需答案:
select ch AS EMP,lvl,
REGEXP_SUBSTR (path, '[^///]+', 1, 3) as lvl1,
REGEXP_SUBSTR (path, '[^///]+', 1, 2) as lvl2,
REGEXP_SUBSTR (path, '[^///]+', 1, 1) as lvl3
from (
SELECT EMP AS CH,manager as par,level as lvl,
SYS_CONNECT_BY_PATH(EMP , '///') as path
FROM TEMP_EMP
START WITH MANAGER IS NULL
CONNECT BY PRIOR EMP = MANAGER);
答案 1 :(得分:0)
Oracle 通过连接,并且它具有伪列级别,可帮助您跟踪层次结构中的位置
答案 2 :(得分:0)
使用以下查询来避免UNION,
select ch AS EMP,lvl,
REGEXP_SUBSTR (path, '[^///]+', 1, 3) as lvl1,
REGEXP_SUBSTR (path, '[^///]+', 1, 2) as lvl2,
REGEXP_SUBSTR (path, '[^///]+', 1, 1) as lvl3
from (
SELECT EMP AS CH,manager as par,level as lvl,
SYS_CONNECT_BY_PATH(EMP , '///') as path
FROM (select emp,lead(emp,1,NULL) over(partition by r order by lvls) manager from (
select val emp,lvls,r from (
select R,lvls,val from (
SELECT emp,lead,manager,row_number()over(order by emp) r FROM TEMP_EMP2) unpivot(val for lvls in (emp as '1', lead as '2',manager as '3') ))))
START WITH MANAGER IS NULL
CONNECT BY PRIOR EMP = MANAGER);