跟踪成员在oracle上更改历史记录

时间:2013-02-21 10:43:07

标签: oracle recursion

我正在尝试编写查询以跟踪成员更改历史记录,但我现在遇到了问题。 这是我在下面使用的表格,

CURRENT_NO, NEW_MEMBER_NO, OLD_MEMBER_NO, SEQ_NO
----------  -------------  -------------  ------ 
 M002       M001           M000           1  
 M002       M002           M001           1  
            M100           M004           1  
            M100           M005           1  
            M101           M100           1  
            M201           M200           1 
            M200           M201           2

我想要做的是跟踪member_no更改历史记录并将CURRENT_NO列更新为currnet成员编号。

这是我想要的结果

CURRENT_NO, NEW_MEMBER_NO, OLD_MEMBER_NO, SEQ_NO
----------  -------------  -------------  ------
 M002       M001           M000           1
 M002       M002           M001           1

 M101       M100           M004           1
 M101       M100           M005           1
 M101       M101           M100           1

 M200       M201           M200           1
 M200       M200           M201           2

在第一行有OLD_MEMBER_NO,我搜索NEW_MEMBER_NO,如果找到,则在第1行将CURRENT_NO更新为第2行的NEW_MEMBER_NO。

CURRENT_NO列显示当前成员没有每一行
1)成员M000变为M001,从M001变为M002所以现在CURRENT_NO列在两行上都是M002 2)它有时被复杂化。 M004和M005 - > M100 - > M101
   这种变化是可能的。对于这种情况,CURRENT_NO都是M101 3)M200 - > M201,然后它再次从M201变为M200。更大的SEQ_NO是新的。所以对于这种情况,CURRENT_NO是M200

我尝试使用像belo,....一样的查询

UPDATE 
       (SELECT A.MBR_# AS MBR_#, 
              b.NEW_MBR_# AS B_NEW_MBR_#, 
              B.OLD_MBR_# AS B_OLD_MBR_#, 
              A.NEW_MBR_# AS A_NEW_MBR_#, 
              A.OLD_MBR_# AS A_OLD_MBR_#  
         FROM BI_MEMBER_HISTORY A, 
              BI_MEMBER_HISTORY B  
        WHERE B.OLD_MBR_# = A.NEW_MBR_#
       ) 
SET MBR_# = B_NEW_MBR_#;

问题是 1)有些时候有2个以上的变化 2)和上面的例子3 ..这使我编写查询很复杂..我知道我的查询有一些问题。

我尝试使用光标或递归查询的过程,但我不知道如何处理它 任何人都可以给我一个线索吗?
提前谢谢你。

1 个答案:

答案 0 :(得分:1)

根据您的要求,您可以使用如下查询找到每行的当前编号:

SQL> WITH DATA AS (
  2  SELECT 'M001' new_no, 'M000' old_no, 1 seq FROM dual
  3  UNION ALL SELECT 'M002', 'M001', 1 FROM dual
  4  UNION ALL SELECT 'M100', 'M004', 1 FROM dual
  5  UNION ALL SELECT 'M100', 'M005', 1 FROM dual
  6  UNION ALL SELECT 'M101', 'M100', 1 FROM dual
  7  UNION ALL SELECT 'M201', 'M200', 1 FROM dual
  8  UNION ALL SELECT 'M200', 'M201', 2 FROM dual
  9  )
 10  SELECT root old_no,
 11         MAX(new_no)
 12            KEEP (DENSE_RANK FIRST ORDER BY seq DESC, lvl DESC) current_no
 13    FROM (SELECT connect_by_root(old_no) root,
 14                 level lvl, new_no, old_no, seq
 15            FROM DATA
 16          CONNECT BY NOCYCLE PRIOR new_no = old_no)
 17   GROUP BY root;

OLD_NO CURRENT_NO
------ ----------
M000   M002
M001   M002
M004   M101
M005   M101
M100   M101
M200   M200
M201   M200

内部查询为每个old_no构建所有子项的列表,并使用CONNECT_BY_ROOT跟踪根目录。

外部查询在所有后代中从每个根的最后一个谱系序列(level desc)中选择谱系的最后一个子项(seq desc)。

您可以将此查询的结果合并到表格中:

MERGE INTO (your_table) t
     USING (above_query) q
        ON (t.old_no = q.old_no)
    WHEN MATCHED THEN UPDATE SET t.current_no = q.current_no;