2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【PL/SQL】比較を行い、片方にのみ存在するレコードを論理削除するSQL

Last updated at Posted at 2019-03-11

2つのテーブルのうち片方にのみ存在するレコードの論理削除

やりたいこと

2つのテーブルを比較し、一方に存在し、もう一方に存在しないレコードを論理削除します。
データ連携などの際に連携されなかったマスタ情報などを更新するために使用します。
UPDATEだけでなく、DELETEなどの応用も可能です。
この処理では「TGTテーブル」に存在し、「WKテーブル」に存在しないものを「TGTテーブル」でUPDATEする場合に使用します。

逆に「WKテーブル」に存在し、「TGTテーブル」に存在しないものを「WKテーブル」からINSERTする場合には「MERGE」文を使用します。
【PL/SQL】MERGE=INSERT+UPDATE

テーブル

WKテーブル

EMP_CD(主キー) EMP_NAME
E111111 aaa
E222222 bbb

TGTテーブル

EMP_CD(主キー) EMP_NAME DEL_FLG(削除区分)
E111111 aaa 0
E222222 bbb 0
E333333 ccc 0

⇒TGTテーブルのみに存在するレコードのDEL_FLGを1として論理削除を行いたい。

EMP_CD(主キー) EMP_NAME DEL_FLG(削除区分)
E111111 aaa 0
E222222 bbb 0
E333333 ccc 1

コード(主キーが1つの場合)

UPDATE tgt tgt
SET    tgt.del_flg = '1'    -- del_flgを1に更新
WHERE  tgt.emd_cd =
    (   SELECT
            tgt_wk.emd_cd
        FROM tgt tgt_wk                -- TGTテーブル
        LEFT OUTER JOIN wk wk          -- WKテーブル
        ON tgt_wk.emd_cd = wk.emd_cd
        WHERE wk.emd_cd IS NULL        -- 主キーがNULLの項目をキャッチ
    );

または

UPDATE tgt tgt
SET    tgt.del_flg = '1'    -- del_flgを1に更新
WHERE  NOT EXISTS
       (SELECT *
        FROM   wk
        WHERE  tgt.emp_cd = wk.emp_cd
        );

EXISTS は後に続く括弧で囲まれた副問い合わせの結果が「存在すれば (TRUE)」、「存在しなければ (FALSE)」を戻します。
NOT EXISTSはその逆のため、「存在しなければ (TRUE)」、「存在すれば (FALSE)」を戻します。

コード(主キーが2つ以上の場合)

主キーがemp_cdemp_cd2の場合には以下のような記述になります。

UPDATE tgt tgt
SET    tgt.del_flg = '1'    -- del_flgを1に更新
WHERE (  tgt.emd_cd,
         tgt.emd_cd2
     ) IN
    (   SELECT
            tgt_wk.emd_cd,
            tgt_wk.emd_cd2
        FROM tgt tgt_wk                -- TGTテーブル
        LEFT OUTER JOIN wk wk          -- WKテーブル
        ON tgt_wk.emd_cd = wk.emd_cd
        WHERE wk.emd_cd  IS NULL        -- 主キーがNULLの項目をキャッチ
        AND   wk.emd_cd2 IS NULL
    );

または

UPDATE tgt tgt
SET    tgt.del_flg = '1'    -- del_flgを1に更新
WHERE  NOT EXISTS
       (SELECT *
        FROM   wk
        WHERE  tgt.emp_cd  = wk.emp_cd
        AND    tgt.emp_cd2 = wk.emp_cd2
        );

NOT EXISTS とNOT IN

NOT EXISTSではなくNOT INを使用した場合、副問い合わせの結果が NULLとなる場合、結果はUNKNOWNになるため NOT EXISTS の場合と異なる挙動を取ります。NULLについて特別な処理を行わないならば、NOT EXISTSが無難です。

2
1
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?