Oracle 11g PLSQL - 随着时间的推移将记录拆分为组成记录 - 行生成
Oracle 11g PLSQL - Splitting A Record Out Into Constituent Records Over Time - Row Generating
我有一个包含数字字段 "WR_EST_MHs" 的数据集(视图)。如果该字段超过一定数量的工时(120 或 60,取决于其他 2 个字段的值),我需要将其拆分为连续记录,并将这些工时分布在未来几周内。
OH_UG_Key 和 1kMCM_Flag 字段确定拆分的阈值。例如,如果 OH_UG = 1 AND 1kMCM_Flag = 'N' 并且 WR_EST_MHs > 120,则根据需要将 WR_EST_MHs 值分布到尽可能多的记录上,以 120 MH 为增量,仅更改 WRSchedDate 和 WRSchedDate_Key 字段(每个字段提前一周)。
每个OH_UG/1kMCM_Flag/WR_EST_MHs场景如下:
这是我需要做的一个例子:
我认为这样的东西可能有用,但我以前没有用过关卡:
with cte as
2 (Select * from "STJOF"."vfactScheduledWAWork"
5 )
6 select WR_Key, WP_Key, WRShedDate, DistSA_Key_Hash, CrewHQ_Key_Hash, Priority_Key_Hash, JobType_Key_Hash, WRStatus_Key_Hash, PerfBy_Key, OHUG_Key, 1kMCM_Flag, WR_EST_MHs
7 from cte cross join table(cast(multiset(select level from dual
8 connect by level >= WR_EST_MHs / 120
9 ) as sys.odcinumberlist))
10 order by WR_Key;
我也认为这可以用我有一点经验的 "tally table" 来完成。我真的不知道从哪里开始。
所以我想说 "Tally Table" 如果应用正确,它会起作用。 (或者,在这种情况下,计数视图。)
首先,将小时突破的逻辑分解成一个函数,这样我们就不会像这样到处都是 case:
CREATE OR REPLACE FUNCTION get_hour_breakout(in_ohug_key IN NUMBER, in_1kmcm_flag in varchar2, in_tot_hours in number)
RETURN number
IS hours number;
BEGIN
hours:=
case when in_ohug_key=2 and in_1kmcm_flag='N' and in_tot_hours>60 then 60 else
case when in_ohug_key=2 and in_1kmcm_flag='Y' and in_tot_hours>60 and in_tot_hours<=120 then 60 else
case when in_ohug_key=2 and in_1kmcm_flag='Y' and in_tot_hours>120 then 120 else
120
end
end
end;
RETURN(hours);
END get_hour_breakout;
这样,如果小时突破逻辑发生变化,可以在一个地方进行调整。
其次,像这样加入动态 "tally" 视图:
select wr_key,
WP_Key,
wrscheddate+idxkey.nnn*7 wrscheddate,
to_char(wrscheddate+idxkey.nnn*7,'yyyymmdd') WRSchedDate_Key,
OHUG_Key,
kMCM_Flag,
case when (wr_est_mhs-idxkey.nnn*get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs))>=get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) then get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) else wr_est_mhs-idxkey.nnn*get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) end wr_est_mhs
from yourView inner join (SELECT ROWNUM-1 nnn
FROM ( SELECT 1 just_a_column
FROM dual
CONNECT BY LEVEL <= 52
)
) idxkey on vwrk.wr_est_mhs/get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) > idxkey.nnn
通过使用按级别连接,我们实际上生成了一堆零索引行,然后通过将小时数除以大于 feed 数的突破来加入它,我们为每个组得到几行。
例如,如果函数 returns 120 且小时数为 100,则您得到一行,因此它保持 1 到 1。如果函数 returns 120 且小时数为 500,但是,您得到 5 行,因为 500/120=4.1666666...,在连接中给出行 4、3、2、1、0。然后剩下的就是简单的数学来确定每次突破的小时数。
这也可以通过将函数调用移动到下视图来改进,这样它每行只使用一次。内联计数视图可以变成它自己的视图,这取决于您需要构建到它的可维护性。
我有一个包含数字字段 "WR_EST_MHs" 的数据集(视图)。如果该字段超过一定数量的工时(120 或 60,取决于其他 2 个字段的值),我需要将其拆分为连续记录,并将这些工时分布在未来几周内。
OH_UG_Key 和 1kMCM_Flag 字段确定拆分的阈值。例如,如果 OH_UG = 1 AND 1kMCM_Flag = 'N' 并且 WR_EST_MHs > 120,则根据需要将 WR_EST_MHs 值分布到尽可能多的记录上,以 120 MH 为增量,仅更改 WRSchedDate 和 WRSchedDate_Key 字段(每个字段提前一周)。
每个OH_UG/1kMCM_Flag/WR_EST_MHs场景如下:
这是我需要做的一个例子:
我认为这样的东西可能有用,但我以前没有用过关卡:
with cte as
2 (Select * from "STJOF"."vfactScheduledWAWork"
5 )
6 select WR_Key, WP_Key, WRShedDate, DistSA_Key_Hash, CrewHQ_Key_Hash, Priority_Key_Hash, JobType_Key_Hash, WRStatus_Key_Hash, PerfBy_Key, OHUG_Key, 1kMCM_Flag, WR_EST_MHs
7 from cte cross join table(cast(multiset(select level from dual
8 connect by level >= WR_EST_MHs / 120
9 ) as sys.odcinumberlist))
10 order by WR_Key;
我也认为这可以用我有一点经验的 "tally table" 来完成。我真的不知道从哪里开始。
所以我想说 "Tally Table" 如果应用正确,它会起作用。 (或者,在这种情况下,计数视图。)
首先,将小时突破的逻辑分解成一个函数,这样我们就不会像这样到处都是 case:
CREATE OR REPLACE FUNCTION get_hour_breakout(in_ohug_key IN NUMBER, in_1kmcm_flag in varchar2, in_tot_hours in number)
RETURN number
IS hours number;
BEGIN
hours:=
case when in_ohug_key=2 and in_1kmcm_flag='N' and in_tot_hours>60 then 60 else
case when in_ohug_key=2 and in_1kmcm_flag='Y' and in_tot_hours>60 and in_tot_hours<=120 then 60 else
case when in_ohug_key=2 and in_1kmcm_flag='Y' and in_tot_hours>120 then 120 else
120
end
end
end;
RETURN(hours);
END get_hour_breakout;
这样,如果小时突破逻辑发生变化,可以在一个地方进行调整。
其次,像这样加入动态 "tally" 视图:
select wr_key,
WP_Key,
wrscheddate+idxkey.nnn*7 wrscheddate,
to_char(wrscheddate+idxkey.nnn*7,'yyyymmdd') WRSchedDate_Key,
OHUG_Key,
kMCM_Flag,
case when (wr_est_mhs-idxkey.nnn*get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs))>=get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) then get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) else wr_est_mhs-idxkey.nnn*get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) end wr_est_mhs
from yourView inner join (SELECT ROWNUM-1 nnn
FROM ( SELECT 1 just_a_column
FROM dual
CONNECT BY LEVEL <= 52
)
) idxkey on vwrk.wr_est_mhs/get_hour_breakout(ohug_key, kmcm_flag, wr_est_mhs) > idxkey.nnn
通过使用按级别连接,我们实际上生成了一堆零索引行,然后通过将小时数除以大于 feed 数的突破来加入它,我们为每个组得到几行。
例如,如果函数 returns 120 且小时数为 100,则您得到一行,因此它保持 1 到 1。如果函数 returns 120 且小时数为 500,但是,您得到 5 行,因为 500/120=4.1666666...,在连接中给出行 4、3、2、1、0。然后剩下的就是简单的数学来确定每次突破的小时数。
这也可以通过将函数调用移动到下视图来改进,这样它每行只使用一次。内联计数视图可以变成它自己的视图,这取决于您需要构建到它的可维护性。