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 列を現在のメンバー番号として更新することです。

これは私が下に望む結果です

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 から M002 に変更されたため、CURRENT_NO 列は両方の行で M002 になりました
2) 複雑になる場合があります。M004 と M005 -> M100 -> M101
この変更は可能です。この場合、CURRENT_NO はすべて M101 です。
3) M200 -> M201、M201 から M200 に再び変化します。大きい方の SEQ_NO が新しいものです。この場合、CURRENT_NO は M200 です。


そして、ベロのようなクエリを使用しようとしました,,....

アップデート
       (A.MBR_# を 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..これにより、クエリの記述が複雑になります..クエリに問題があることはわかっています。

カーソルまたは再帰クエリでプロシージャを使用しようとしましたが、対処方法がわかりません。
誰でも私に手がかりを与えることができますか?

前もって感謝します。

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 に答える