Oracle从另一个表更新数据,但使用复合键

问题描述

question一样,我需要将数据从一个表更新到另一个表。当我所有的键都匹配时,合并效果很好,但是当我尝试不对一个键进行匹配,而是找到其余键上匹配的最新记录时,合并似乎会丢失。

我有一个包含一堆记录的表,并且我试图找到STR_VAL的先前值,但它也必须通过STR_NAME在BASERATE和SUBKEY1上匹配。我制作了一个子表,其中包含在给定日期范围内已更改的所有记录,并且它们具有PREV_STR_VAL和PREV_COMPOUND_RATE的其他字段,以及指示已更新的标志。所以...原始表中的数据如下:

BASERATE   BASERATE_DATE COMPOUND_RATE    SUBKEY1    SUBKEY2    SUBKEY3   STR_NAME   STR_VAL   CUR  STR_DT   END_DT
RATE001    8/15/2020     RATE001-081520   mineRAL    ROCK       IGNEOUS   Lava       No        Y    8/15/20
RATE001    8/15/2020     RATE001-081520   mineRAL    ROCK       IGNEOUS   Pumice     13        Y    8/17/20
RATE001    8/15/2020     RATE001-081520   ANIMAL     MAMMAL     COW       Guernsey   brown     Y    8/15/20
RATE001    8/15/2020     RATE001-081520   mineRAL    ROCK       IGNEOUS   Pumice     38        N    8/15/20  8/17/20
RATE001    4/23/2020     RATE001-042320   ANIMAL     MAMMAL     COW       Guernsey   Spotted   Y    4/23/20
RATE001    5/15/2019     RATE001-051519   ANIMAL     MAMMAL     COW       Guernsey   Milking   Y    5/15/19

查询有效(假设我正确混淆了...)

merge into TMP_CHANGES curr
using 
(select *
   from TMP_BO_DATA_TBL) prv
  on (curr.baserate = prv.BASERATE  -- same base rate
 and curr.COMPOUND_RATE = prv.COMPOUND_RATE -- and same rate altogether 
 and curr.SUBKEY1 = prv.SUBKEY1  -- and of course the other key fields match
 and curr.SUBKEY2 = prv.SUBKEY2
 and curr.SUBKEY3 = prv.SUBKEY3
 and curr.STR_NAME  = prv.STR_NAME 
 and prv.cur = 'N' -- but not the current record
 and trunc(curr.STR_DT) = trunc(prv.END_DT)  -- but the exact prevIoUs record
 )
when matched then update set
  curr.prev_COMPOUND_RATE  = prv.COMPOUND_RATE,curr.prev_STR_VAL = prv.STR_VAL
;

它会在Pumice上找到匹配的记录,并更新我的TMP_CHANGES表,使其先前的compound_rate和先前的str_val为RATE001-081520和38。

我的挑战是以相同的BASERATE,但以不同的COMPOUND_RATE,例如在Cow记录中进行更新。我想要不匹配的最新版本-根西岛(Spotted Guernsey)

我的最终目标是这样的数据:

BASERATE   BASERATE_DATE COMPOUND_RATE    SUBKEY1    SUBKEY2    SUBKEY3   STR_NAME   STR_VAL   CUR  STR_DT   END_DT   PREV_COMPOUND_RATE   PREV_STR_VAL   UPDATE_FLG
RATE001    8/15/2020     RATE001-081520   mineRAL    ROCK       IGNEOUS   Lava       No        Y    8/15/20
RATE001    8/15/2020     RATE001-081520   mineRAL    ROCK       IGNEOUS   Pumice     13        Y    8/17/20           RATE001-081520       38             Y
RATE001    8/15/2020     RATE001-081520   ANIMAL     MAMMEL     COW       Guernsey   brown     Y    8/15/20           RATE001-042320       Spotted        Y

而且,此查询将永远进行下去。出了点问题。

-- this is taking forever!
merge into TMP_CHANGES curr
using 
(select *
   from TMP_BO_DATA_TBL) prv
  on (curr.BASERATE = prv.BASERATE  -- same base rate
 and curr.COMPOUND_RATE <> prv.COMPOUND_RATE -- but a prevIoUs rate 
 and curr.SUBKEY1 = prv.SUBKEY1  -- and of course the other key fields match
 and curr.SUBKEY2 = prv.SUBKEY2
 and curr.SUBKEY3 = prv.SUBKEY3
 and curr.STR_NAME = prv.STR_NAME
 and curr.UPDATE_FLG is null -- don't update if it's already updated
 and prv.cur = 'Y' -- and an active one with the base rate
 and prv.BASERATE_DATE = (select max (BASERATE_DATE)  -- but rather prevIoUs one most current
                             from CM_CI1558A_TMP_BO_DATA_TBL tbl2
                            where tbl2.base_rate = prv.base_rate
                              and tbl2.COMPOUND_RATE <> curr.COMPOUND_RATE                            
                              and tbl2.SUBKEY1 = prv.SUBKEY1
                              and tbl2.SUBKEY2 = prv.SUBKEY2
                              and tbl2.SUBKEY3 = prv.SUBKEY3
                              and tbl2.STR_NAME = prv.STR_NAME
                              and tbl2.cur = 'Y')
 )
when matched then update set
  curr.prev_COMPOUND_RATE = prv.COMPOUND_RATE,curr.prev_STR_VAL = prv.STR_VAL
;

我的变更表有298条记录。我的源表具有索引,只有188390条记录。也许我没有合适的索引?还是有一种更好的方法来查找和更新底价相同但复合率不同的记录?我是否陷入某种无限循环?我只能说我杀死了查询,因为无论发生什么事情,它都不需要花很长时间。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)