2013-02-21 124 views
1

我試圖編寫查詢來跟蹤成員更改歷史記錄,但現在我遇到了問題。 這是我在下面用表,在oracle上跟蹤成員更改歷史記錄

 
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,如果我找到它,然後在第一列作爲NEW_MEMBER_NO在第二排更新CURRENT_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。


我試圖用查詢像貝羅,, ....

 
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

考慮你的要求,你可以找到像這樣的一個查詢的每個行的當前數量:

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

外部查詢從所有後代中選擇每個根的最後一個譜系序列(seq desc)的譜系的最後一個孩子(level 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; 
+0

感謝您的回答。它似乎是遞歸查詢,不是嗎?據我所知它在oracle 11g上受支持。我正在使用10g。和..我有超過10,000行的表格。我想我需要分析你的查詢。謝謝! – nick 2013-02-21 11:40:29

+0

這個查詢應該在10g上正常工作。 'CONNECT_BY_ROOT'和'NO CYCLE'是我認爲的10g功能。標準的分層查詢已經可以用於**非常非常非常長的時間([Oracle 2](http://www.orafaq.com/wiki/Oracle_2)!!!在我出生前幾個月:)。 – 2013-02-21 11:59:44