簡體   English   中英

具有多個條件的SQL合並語句

[英]SQL merge statement with multiple conditions

我有一些要在SQL上(在PL / SQL塊內)實現的業務規則的要求:我需要評估這些規則,並根據結果執行相應的更新,刪除或插入目標表。

我的數據庫模型包含一個“ staging”和一個“ real”表。 真實表存儲了過去插入的記錄,而暫存表包含需要合並到真實表中的某處的“新”數據。

基本上,這些是我的業務規則:

  1. 分期 在沒有 真實之間三角洲- >行插入到現實
  2. 實際 減號 分段之間的增量->從真實 減號中 刪除
  3. PK相同但其他字段不同的行: Update

(那些“ MINUS ”將比較所有字段以獲得相等性並區分第三種情況)

我還沒有想出通過使用merge語句在規則之間沒有重疊的情況下完成這些任務的方法:對合並結構有任何建議嗎? 是否可以在同一合並中一起完成所有操作?

謝謝!

如果我正確理解您的任務,則應使用以下代碼來完成任務:

--drop table real;
--drop table stag;

create table real (
  id NUMBER,
  col1 NUMBER,
  col2 VARCHAR(10)
);

create table stag (
  id NUMBER,
  col1 NUMBER,
  col2 VARCHAR(10)
);

insert into real values (1, 1, 'a');
insert into real values (2, 2, 'b');
insert into real values (3, 3, 'c');
insert into real values (4, 4, 'd');
insert into real values (5, 5, 'e');
insert into real values (6, 6, 'f');
insert into real values (7, 6, 'g'); -- PK the same but at least one column different
insert into real values (8, 7, 'h'); -- PK the same but at least one column different
insert into real values (9, 9, 'i');
insert into real values (10, 10, 'j'); -- in real but not in stag

insert into stag values (1, 1, 'a');
insert into stag values (2, 2, 'b');
insert into stag values (3, 3, 'c');
insert into stag values (4, 4, 'd');
insert into stag values (5, 5, 'e');
insert into stag values (6, 6, 'f');
insert into stag values (7, 7, 'g'); -- PK the same but at least one column different
insert into stag values (8, 8, 'g'); -- PK the same but at least one column different
insert into stag values (9, 9, 'i');
insert into stag values (11, 11, 'k'); -- in stag but not in real

merge into real
     using (WITH w_to_change AS (
              select *
                from (select stag.*, 'I' as action from stag
                       minus
                      select real.*, 'I' as action from real
                     )
               union (select real.*, 'D' as action from real
                       minus 
                      select stag.*, 'D' as action from stag
                     )
            )
            , w_group AS (
              select id, max(action) as max_action
                from w_to_change
               group by id
            )
            select w_to_change.*
              from w_to_change
              join w_group
                on w_to_change.id = w_group.id
               and w_to_change.action = w_group.max_action
           ) tmp
   on (real.id = tmp.id)
 when matched then
   update set real.col1 = tmp.col1, real.col2 = tmp.col2
   delete where tmp.action = 'D'
 when not matched then
   insert (id, col1, col2) values (tmp.id, tmp.col1, tmp.col2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM