1

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

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,如果找到它,则将第一行的 CURRENT_NO 更新为第二行的 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 之类的查询,,....

更新
       (选择 A.MBR_# 作为 MBR_#,
              b.NEW_MBR_# 作为 B_NEW_MBR_#,
              B.OLD_MBR_# AS B_OLD_MBR_#,
              A.NEW_MBR_# 作为 A_NEW_MBR_#,
              A.OLD_MBR_# AS A_OLD_MBR_#  
         从 BI_MEMBER_HISTORY A,
              BI_MEMBER_HISTORY B  
        其中 B.OLD_MBR_# = A.NEW_MBR_#
       )
SET MBR_# = B_NEW_MBR_#;

问题是
1) 有时有超过 2 个更改。
2)和上面的例子3..这让我写查询很复杂..我知道我的查询有问题。

我尝试使用带有游标或递归查询的过程,但我不知道如何处理它。
谁能给我一个线索?

先感谢您。

4

1 回答 1

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;
于 2013-02-21T11:19:12.940 回答