尝试查找值从当前表和历史记录表中更改的最后时间

时间:2018-06-10 06:19:49

标签: database oracle plsql

我们有一些变量字段保存在两个表中。

表1:这将维护字段的当前快照

表2:对变量字段进行任何更改,将所有行从表1 移动到表2 ,然后再次插入所有行使用更改后的值返回表1

示例:

快照1

表1:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS
Group1     F1         V1          T1
Group1     F2         V2          T1
Group1     F3         V3          T1
Group2     F1         VX          TX

表2:

NO ROWS

快照2 - > Group1 F3值已经达到V33

表1:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS
Group1     F1         V1          T2
Group1     F2         V2          T2
Group1     F3         V33         T2
Group2     F1         VX          TX

表2:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS HIST_TS
Group1     F1         V1          T1          HT1
Group1     F2         V2          T1          HT2
Group1     F3         V3          T1          HT3

快照3 - > Group1 F2值已更改为V22

表1:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS
Group1     F1         V1          T3
Group1     F2         V22         T3
Group1     F3         V33         T3
Group2     F1         VX          TX

表2:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS HIST_TS
Group1     F1         V1          T1          HT1
Group1     F2         V2          T1          HT2
Group1     F3         V3          T1          HT3
Group1     F1         V1          T2          HT4
Group1     F2         V2          T2          HT5
Group1     F3         V33         T2          HT6

快照4 - > Group1 F3值已更改为V333

表1:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS
Group1     F1         V1          T4
Group1     F2         V22         T4
Group1     F3         V333        T4
Group2     F1         VX          TX

表2:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS HIST_TS
Group1     F1         V1         T1          HT1
Group1     F2         V2         T1          HT2
Group1     F3         V3         T1          HT3
Group1     F1         V1         T2          HT4
Group1     F2         V2         T2          HT5
Group1     F3         V33        T2          HT6
Group1     F1         V1         T3          HT7
Group1     F2         V22        T3          HT8
Group1     F3         V33        T3          HT9

HT 代表历史记录时间表示字段从表1 移至表2

我想在过去2小时内获取哪些字段已根据表1和表2的实际时间戳更改

预期结果:

VAR_GRP    VAR_FLD    VAR_FLD_VAL LST_UPDT_TS
Group1     F2         V22         T3
Group1     F3         V333        T4

1 个答案:

答案 0 :(得分:2)

这是一个答案,它根据您提供的样本从测试数据中选择预期结果集中的记录。我只是因为你的问题并没有完全表达所需的业务规则,所以我用这种方式来表达它,所以这是一个猜测:

select t1.VAR_GRP,  
       t1.VAR_FLD , 
       t1.VAR_FLD_VAL,
       min(case when t1.VAR_FLD_VAL != t2.VAR_FLD_VAL then t1.LST_UPDT_TS
            else t2.min_LST_UPDT_TS end) as LST_UPDT_TS
from table1 t1
     join ( select VAR_GRP,  
                   VAR_FLD , 
                   VAR_FLD_VAL,
                   min(LST_UPDT_TS) over (partition by VAR_GRP, VAR_FLD, VAR_FLD_VAL) min_LST_UPDT_TS,
                   row_number() over (partition by VAR_GRP, VAR_FLD, VAR_FLD_VAL order by HIST_TS desc) rn
            from  table2 
            ) t2 on t1.VAR_GRP = t2.VAR_GRP
                and t1.VAR_FLD = t2.VAR_FLD
where t2.rn = 1
and (t2.min_LST_UPDT_TS >= to_date('2018-06-10 11:00:00', 'yyyy-mm-dd hh24:mi:ss') - (1/24) or  t1.VAR_FLD_VAL != t2.VAR_FLD_VAL) 
group by t1.VAR_GRP,  
       t1.VAR_FLD , 
       t1.VAR_FLD_VAL
/

所以我实施的业务规则是:

  • 计算table2
  • 中记录的LST_UPDT_TS的最小值
  • 如果LST_UPDT_TS的最低值在最近两小时内
  • table1中的值与table2
  • 中的值不匹配
  • 然后包含在结果集中

此处is a LiveSQL demo (free Oracle account required - sorry but SQL Fiddle has been rather flaky of late)

请注意,如果更改是将新(VAR_GRP,VAR_FLD)的记录插入table1或从table1删除记录,则此解决方案不起作用。我不确定您将如何在table2中代表这些活动。

为了其他搜索者的利益,我在评论中将日记实施描述为" bonkers"。为何如此苛刻?因为这个过程产生了许多不必要的工作,并且在讨价还价中丢失了重要的信息:

  1. 日志记录过程会获取VAR_GRP中所有现有记录的快照,这些记录拥有已更改的记录。仅使用旧版本的更改记录填充table2就不那么容易了。
  2. 该进程更新(或者,似乎,删除并重新插入)VAR_GRP中拥有已更改记录的所有现有记录的table1中的所有LST_UPDT_TS值。仅更新已更改记录的时间戳将不那么重要。
  3. 由于该流程会拍摄所有table1条记录的快照,因此如果不进行大量工作,就无法查看table2中哪条记录已更改。
  4. 由于该流程会更新table1中的所有记录,因此无法在未咨询table2的情况下查看每条记录的实际更改时间。
  5. Journalling(AKA审计,历史)是一种开销,因为只要我们在表上执行DML就会触发它。因此,最好尽量减少对数据库的影响;这个实现恰恰相反。它还抛弃了最重要的一条信息 - 哪条记录被更改 - 并要求我们从其他记录中推断出来。表现不佳。

    更好的实施方法是将已更改的table1记录的旧版本插入table2,并使用时间戳标记已更改的table1记录。