[英]SQL merge statement with multiple conditions
I have a requirement with some business rules to implement on SQL (within a PL/SQL block): I need to evaluate such rules and according to the result perform the corresponding update, delete or insert into a target table. 我有一些要在SQL上(在PL / SQL块内)实现的业务规则的要求:我需要评估这些规则,并根据结果执行相应的更新,删除或插入目标表。
My database model contains a "staging" and a "real" table. 我的数据库模型包含一个“ staging”和一个“ real”表。 The real table stores records inserted in the past and the staging one contains "fresh" data coming from somewhere that needs to be merged into the real one. 真实表存储了过去插入的记录,而暂存表包含需要合并到真实表中的某处的“新”数据。
Basically these are my business rules: 基本上,这些是我的业务规则:
(Those " MINUS " will compare ALL the fields to get equality and distinguise the 3rd case) (那些“ MINUS ”将比较所有字段以获得相等性并区分第三种情况)
I haven't figured out the way to accomplish such tasks without overlapping between rules by using a merge statement: Any suggestion for the merge structure? 我还没有想出通过使用merge语句在规则之间没有重叠的情况下完成这些任务的方法:对合并结构有任何建议吗? Is it possible to do it all together within the same merge? 是否可以在同一合并中一起完成所有操作?
Thank you! 谢谢!
If I understand you task correctly following code should do the job: 如果我正确理解您的任务,则应使用以下代码来完成任务:
--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.