【问题标题】:merge query based on when not matched by target oracle SQL基于何时与目标 oracle SQL 不匹配的合并查询
【发布时间】:2016-07-13 05:07:42
【问题描述】:

我想对匹配特定条件的表或表的子集进行合并查询。所以我正在寻找的正是下面的东西 -

merge into table1 as target using table2 as Source on target.col1 = Source.col1
when matched then update
when not matched by target -- row exists in source but not in targer
then insert ;

我了解 when not matched by target 在 oracle 中不受支持。我想知道是否有替代方法可以在单个合并语句中执行相同的操作。基本上我只想在源表中存在行而不是目标表中时插入。

【问题讨论】:

  • 我不明白你为什么需要by target。没有它,它不会像when not matched then insert ... 那样工作吗?
  • 这正是merge 语句的工作原理。不需要by target 替代品。
  • 这里没有 PL/SQL,除非您要求程序解决方案。

标签: sql oracle oracle10g


【解决方案1】:

正如其他人所指出的,BY TARGET 可以为 Oracle 删除,它可以按您的预期工作。这里有一个带有两个表的小脚本,它们显示了这种行为并且它有效。您希望将 temp_test 中的所有行合并到 summary 中,这些行在 temp_test 中但尚未在 summary 中。

create table temp_test 
(
    DT      date,
    Foobar  varchar2(100),
    Step    varchar2(100)
);

create table summary 
(
    DT          date,
    Foobar      varchar2(100),
    Step        varchar2(100),
    OtherFields varchar2(100) NULL
);
/

insert into temp_test values (trunc(sysdate), 'test', '20'); -- should be inserted
insert into temp_test values (trunc(sysdate-1), 'test', '20'); -- already in summary

INSERT into summary (DT, Foobar, Step) VALUES (trunc(sysdate-1), 'test', '20');
select * from temp_test; -- 2 records
select * from summary; -- 1 record


merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
    INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 1 row updated

select* from gui_po_summary; -- 2 rows

-- try to merge again, nothing should be done
merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
    INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 0 rows

delete temp_test; -- 2 rows deleted
-- try to merge again, nothing should be done as we want WHEN NOT MATCHED BY target
merge into summary TARGET
USING temp_test SOURCE
ON (TARGET.DT = SOURCE.DT and TARGET.Foobar = SOURCE.Foobar and TARGET.Step = SOURCE.Step)
WHEN NOT MATCHED THEN
    INSERT (DT, Foobar, Step) VALUES (SOURCE.DT, SOURCE.Foobar, SOURCE.Step);
-- 0 rows

还有WHEN NOT MATCHED BY source 需要Oracle 特殊处理,并在此处回答https://stackoverflow.com/a/48842932/4040068

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    相关资源
    最近更新 更多