我需要在VIEW或Materialized VIEW等表结构中优化下面的数据。请帮忙说明如何实现它。
Employee Manager Management_Chain
vp2221 bg7915 jd613hbs0712sm2389mw6143mc7580ab3793bg7915vp2221
bg7915 ab3793 jd613hbs0712sm2389mw6143mc7580ab3793bg7915
ab3793 mc7580 jd613hbs0712sm2389mw6143mc7580ab3793
rx2131 bg7915 jd613hbs0712sm2389mw6143mc7580ab3793bg7915rx2131
要求是将上述数据转换如下...根据Employee和Management_Chain列添加距离列值(0,1,2,3,4,....)。对于每个员工,都有一个管理链,其中员工ID也是管理链的一部分。
Employee Manager Distance
vp2221 vp2221 0
vp2221 bg7915 1
vp2221 ab3793 2
vp2221 mc7580 3
vp2221 mw6143 4
vp2221 sm2389 5
vp2221 bs0712 6
vp2221 jd613h 7
bg7915 bg7915 0
bg7915 ab3793 1
bg7915 mc7580 2
bg7915 mw6143 3
bg7915 sm2389 4
bg7915 bs0712 5
bg7915 jd613h 6
ab3793 ab3793 0
ab3793 mc7580 1
ab3793 mw6143 2
ab3793 sm2389 3
ab3793 bs0712 4
ab3793 jd613h 5
rx2131 vp2221 0
rx2131 bg7915 1
rx2131 ab3793 2
rx2131 mc7580 3
rx2131 mw6143 4
rx2131 sm2389 5
rx2131 bs0712 6
rx2131 jd613h 7
....
答案 0 :(得分:0)
您可以使用unpivot
执行此操作 -
select employee, val as manager, min_n as distance
from(
select employee,
manager,
case when length(management_chain)/6 >= 1 then substr(management_chain, length(management_chain) - 5, 6) end as min_00,
case when length(management_chain)/6 >= 2 then substr(management_chain, length(management_chain) - 11, 6) end as min_01,
case when length(management_chain)/6 >= 3 then substr(management_chain, length(management_chain) - 17, 6) end as min_02,
case when length(management_chain)/6 >= 4 then substr(management_chain, length(management_chain) - 23, 6) end as min_03,
case when length(management_chain)/6 >= 5 then substr(management_chain, length(management_chain) - 29, 6) end as min_04,
case when length(management_chain)/6 >= 6 then substr(management_chain, length(management_chain) - 35, 6) end as min_05,
case when length(management_chain)/6 >= 7 then substr(management_chain, length(management_chain) - 41, 6) end as min_06,
case when length(management_chain)/6 >= 8 then substr(management_chain, length(management_chain) - 47, 6) end as min_07,
case when length(management_chain)/6 >= 9 then substr(management_chain, length(management_chain) - 53, 6) end as min_08,
case when length(management_chain)/6 >= 10 then substr(management_chain, length(management_chain) - 59, 6) end as min_09
from tbl
) unpivot (
val for (min_n) in
(
min_00 as 0,
min_01 as 1,
min_02 as 2,
min_03 as 3,
min_04 as 4,
min_05 as 5,
min_06 as 6,
min_07 as 7,
min_08 as 8,
min_09 as 9
)
);
小提琴: http://sqlfiddle.com/#!4/99cc5/3/0
如果management_chain总是有10名或更少的员工,则上述工作将有效。如果可能还有更多,则需要根据需要添加其他行。如果有更少,这不是问题,正如您在演示中看到的那样,默认情况下,unpivot不包含空值(并且内联视图中的case语句确保在这些情况下使用空值)。
答案 1 :(得分:0)
Oracle 11g R2架构设置:
CREATE TABLE NEEDS_REFACTORING ( Employee, Manager, Management_Chain ) AS
SELECT 'vp2221','bg7915','jd613hbs0712sm2389mw6143mc7580ab3793bg7915vp2221' FROM DUAL
UNION ALL SELECT 'bg7915','ab3793','jd613hbs0712sm2389mw6143mc7580ab3793bg7915' FROM DUAL
UNION ALL SELECT 'ab3793','mc7580','jd613hbs0712sm2389mw6143mc7580ab3793' FROM DUAL
UNION ALL SELECT 'rx2131','bg7915','jd613hbs0712sm2389mw6143mc7580ab3793bg7915rx2131' FROM DUAL;
查询1 :
SELECT EMPLOYEE,
SUBSTR( MANAGEMENT_CHAIN, 6*COLUMN_VALUE - 5, 6 ) AS MANAGER,
LENGTH(MANAGEMENT_CHAIN)/6 - COLUMN_VALUE AS DISTANCE
FROM NEEDS_REFACTORING r,
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY 6*LEVEL <= LENGTH( r.MANAGEMENT_CHAIN )
)
AS SYS.ODCINUMBERLIST
)
)
ORDER BY 1,3
<强> Results 强>:
| EMPLOYEE | MANAGER | DISTANCE |
|----------|---------|----------|
| ab3793 | ab3793 | 0 |
| ab3793 | mc7580 | 1 |
| ab3793 | mw6143 | 2 |
| ab3793 | sm2389 | 3 |
| ab3793 | bs0712 | 4 |
| ab3793 | jd613h | 5 |
| bg7915 | bg7915 | 0 |
| bg7915 | ab3793 | 1 |
| bg7915 | mc7580 | 2 |
| bg7915 | mw6143 | 3 |
| bg7915 | sm2389 | 4 |
| bg7915 | bs0712 | 5 |
| bg7915 | jd613h | 6 |
| rx2131 | rx2131 | 0 |
| rx2131 | bg7915 | 1 |
| rx2131 | ab3793 | 2 |
| rx2131 | mc7580 | 3 |
| rx2131 | mw6143 | 4 |
| rx2131 | sm2389 | 5 |
| rx2131 | bs0712 | 6 |
| rx2131 | jd613h | 7 |
| vp2221 | vp2221 | 0 |
| vp2221 | bg7915 | 1 |
| vp2221 | ab3793 | 2 |
| vp2221 | mc7580 | 3 |
| vp2221 | mw6143 | 4 |
| vp2221 | sm2389 | 5 |
| vp2221 | bs0712 | 6 |
| vp2221 | jd613h | 7 |