当"不匹配时,如何在合并中执行两个不同的操作"

时间:2016-03-21 10:04:29

标签: sql oracle merge

我有这两个表

TABLE1
nrb   score  note  source
nrb1    500  abc   e1
nrb2    500  def   e1

TABLE2
nrb   score  note  source
nrb1    500  gls   e1
nrb3    500  dls   e1

有三种情况我想要执行不同的操作。我需要用新值修改Table1:

  1. 匹配时(由NRB)(f.ex。" nrb1")我想保持table1nrb的值,所以基本上:什么都不做有了这条记录

  2. 当不匹配时#1:nrb中有table2table1中没有'nrb3'(例如nrb)我想插入此值{ {1}}从table2table1

  3. 当不匹配#2时:如果nrb中有table1table2中没有'nrb2'(例如score),我想更改table1TABLE1 nrb score note source nrb1 500 abc e1 [stays the same] nrb2 5 def e1 [score changed] nrb3 500 dls e1 [new record from table2] 中从500到5

  4. 所以最后看起来应该是这样的:

    merge

    我需要使用Oracle的{{1}}声明执行此任务,但我不知道如何执行两项不同的操作。

2 个答案:

答案 0 :(得分:3)

您无法在单次合并中执行此操作。 when matched子句只能 插入,而不是更新,如the syntax diagram所示。

enter image description here

同样,merge into table1 t1 using (select * from table2) t2 on (t2.nrb = t1.nrb) when not matched then insert (nrb, score, note, source) values (t2.nrb, t2.score, t2.note, t2.source); 子句只能 更新,而不能插入。你不能在它们之间混合搭配。

您必须拥有单独的更新声明。您可以合并以执行第一部分:

insert into table1 (nrb, score, note, source)
select t2.nrb, t2.score, t2.note, t2.source
from table2 t2
where not exists (
  select null
  from table1 t1
  where t1.nrb = t2.nrb
);

select * from table1;

NRB       SCORE NOT SO
---- ---------- --- --
nrb1        500 abc e1
nrb2        500 def e1
nrb3        500 dls e1

或做同等的插入:

update table1 t1
set score = score/100 -- or fixed value 5; unclear which you need
where not exists (
  select null
  from table2 t2
  where t2.nrb = t1.nrb
);

select * from table1;

NRB       SCORE NOT SO
---- ---------- --- --
nrb1        500 abc e1
nrb2          5 def e1
nrb3        500 dls e1

然后无论你做什么,都要更新没有匹配的地方:

using

如果真的想要通过合并进行更新,但它会使table1子句更复杂 - table2的子集没有结果记录在merge into table1 t1 using ( select * from table1 t1 where not exists ( select null from table2 t2 where t2.nrb = t1.nrb)) t2 on (t2.nrb = t1.nrb) when matched then update set t1.score = score/100; - 所以我没有看到任何好处:

{{1}}

答案 1 :(得分:3)

您需要使用两个不同的 SQL 执行两个单独的任务。因为 MERGE 不支持 WHEN NOT MATCHED 条件的 UPDATE 条款。

  • MERGE INSERT
  • 更新不存在

<强>设置

SQL> CREATE TABLE t1(
  2  nrb VARCHAR2(10), score NUMBER, note VARCHAR2(10), SOURCE VARCHAR2(10)
  3  );

Table created.

SQL> INSERT INTO t1 VALUES('nrb1', 500, 'abc', 'e1');

1 row created.

SQL> INSERT INTO t1 VALUES('nrb2', 500, 'def', 'e1');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> CREATE TABLE t2(
  2  nrb VARCHAR2(10), score NUMBER, note VARCHAR2(10), SOURCE VARCHAR2(10)
  3  );

Table created.

SQL> INSERT INTO t2 VALUES('nrb1', 500, 'gls', 'e1');

1 row created.

SQL> INSERT INTO t2 VALUES('nrb3', 500, 'dls', 'e1');

1 row created.

SQL> COMMIT;

Commit complete.

MERGE INSERT :插入不匹配的行

SQL> MERGE INTO t1
  2  USING t2
  3  ON (t1.nrb = t2.nrb)
  4  WHEN NOT MATCHED THEN
  5    INSERT
  6      (
  7        nrb,
  8        score,
  9        note,
 10        SOURCE
 11      )
 12      VALUES
 13      (
 14        t2.nrb,
 15        t2.score,
 16        t2.note,
 17        t2.SOURCE
 18      );

1 row merged.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM t1;

NRB             SCORE NOTE       SOURCE
---------- ---------- ---------- ----------
nrb1              500 abc        e1
nrb2              500 def        e1
nrb3              500 dls        e1

UPDATE 语句:使用自定义值

更新不匹配的行
SQL> UPDATE t1
  2  SET    score = 5
  3  WHERE  NOT EXISTS (SELECT NULL
  4                     FROM   t2
  5                     WHERE  t1.nrb = t2.nrb);

1 row updated.

SQL>                    COMMIT;

Commit complete.

SQL> SELECT * FROM t1;

NRB             SCORE NOTE       SOURCE
---------- ---------- ---------- ----------
nrb1              500 abc        e1
nrb2                5 def        e1
nrb3              500 dls        e1

注意只使用INSERT代替 MERGE ,您只需编写一个 INSERT 语句即可。虽然,从10g开始,MATCHED和NOT MATCHED子句是可选的,因此您可以使用单个INSERT或单个UPDATE语句。