如何在Oracle中多次更新与另一个表连接的表?

Posted

技术标签:

【中文标题】如何在Oracle中多次更新与另一个表连接的表?【英文标题】:How to update a table joined with another table multiple times in Oracle? 【发布时间】:2018-12-11 07:41:03 【问题描述】:

我的表中有三个字段,我想通过三次加入另一个表来更新它们。我知道我必须使用merge into,但是我找不到任何类似的查询,它使用merge intojoin 多次只使用一个表。

select 语句是这样的:

select * from TABLE t
inner join DESTINATION_TABLE d1
on t.CODE1 = d1.CODE
inner join DESTINATION_TABLE d2
on t.CODE2 = d2.CODE
inner join DESTINATION_TABLE d3
on t.CODE3 = d3.CODE

现在如何使用d1d2d3 中的字段更新TABLE 中的三个字段(FIELD1FIELD2FIELD3)? p>

编辑:

原来的查询是:

select * from TOTAL
inner join GROUP_LEVEL_DETAIL gl1
on gl1.NAME = substr(GL, 1, instr(GL, ' -', 1))
inner join GROUP_LEVEL_DETAIL gl2
on GL2.NAME = replace(substr(GL, instr(GL, ' -', 1, 1), instr(GL, ' -', 1, 2) - instr(GL, ' -', 1, 1)), ' - ', '')
inner join GROUP_LEVEL_DETAIL gl3
on gl3.NAME = replace(substr(GL, instr(GL, '-', 1, 2), 500), '- ', '')

TOTAL 的样本数据为:

  ID                GL                GL1_CODE   GL2_CODE   GL3_CODE
-----  ----------------------------- ---------- ---------- -----------
  1     Sample1 - Sample2 - Sample3    null        null       null
  2     John - Jack - Harry            null        null       null

GROUP_LEVEL_DETAIL 的样本数据为:

  CODE         NAME        LEVEL_NO
---------  -----------   ------------
  SMP1       Sample1           1
  SMP2       Sample2           2
  SMP3       Sample3           3
  JCK1       Jack              1
  JHN2       John              2
  HRY3       Harry             3

我希望我的TOTAL 表在更新后变成这样:

  ID                GL                GL1_CODE   GL2_CODE   GL3_CODE
-----  ----------------------------- ---------- ---------- -----------
  1     Sample1 - Sample2 - Sample3    SMP1        SMP2       SMP3
  2     John - Jack - Harry            JCK1        JHN2       HRY3

【问题讨论】:

我认为您需要提供一些样本数据预期结果,或者您可以设置问题演示,例如dbfiddle.uk 字段属于哪个表,由d1 d2 d3中的哪些列更新??? 好的,我把原始查询和真实数据放上来。 @APC 现在我更新了问题。我不是故意浪费任何人的时间。我只是这样写的,以防止过于复杂。 【参考方案1】:

根据您修改后的问题,我认为解决方案是在子查询中组装 GROUP_LEVEL_DETAIL 名称,以创建一个可以加入 TOTAL 表的键。

merge into TOTAL t
using ( select d1.code as d1_code
               , d2.code as d2_code
               , d3.code as d3_code
               , d1.name || ' - ' ||
                 d2.name || ' - ' ||
                 d3.name as joined_code
         from  GROUP_LEVEL_DETAIL d1
         cross join GROUP_LEVEL_DETAIL d2
         cross join GROUP_LEVEL_DETAIL d3
         where d1.level_no = 1
         and   d2.level_no = 2
         and   d3.level_no = 3  
       ) d
on ( t.gl = d.joined_code )
when matched then
    update 
    set t.gl_code1 = d.d1_code
        ,  t.gl_code2 = d.d2_code
        ,  t.gl_code3 = d.d3_code

USING 子查询从 GROUP_LEVEL_DETAIL 生成记录的所有可能排列的结果集。在您修改后,我包含了一个 WHERE 子句来强制执行隐含规则 GL = 'level 1 - level 2 - level 3'。您可能不希望这样做(可能不是 TOTAL 中的每条记录都有有效的总帐)或扩展 WHERE 子句以应用有关有效组合的任何其他规则。

【讨论】:

这就是我想要的。我相信您在我编辑之前已经写了正确的答案。谢谢。【参考方案2】:

当连接基于主键或唯一索引时,您应该能够执行以下操作:

--create tables and unix index
create table table1 (code number, field1 number, field2 number, field3 number);
create unique index table1_code_inx on table1 (code);

create table table2 (code number, field1 number, field2 number, field3 number);
create unique index table2_code_inx on table2 (code);

-- update data from table2 to table1
update( select a.FIELD1 A_FIELD1, a.FIELD2 A_FILED2, a.FIELD3 A_FIELD3,
               b.FIELD1 B_FIELD1, b.FIELD2 B_FILED2, b.FIELD3 B_FIELD3 
          from TABLE1 a, TABLE2 b
          where a.CODE = b.CODE )
set A_FIELD1 = B_FIELD1,
    A_FILED2 = B_FILED2,
    A_FIELD3 = B_FIELD3;

【讨论】:

以上是关于如何在Oracle中多次更新与另一个表连接的表?的主要内容,如果未能解决你的问题,请参考以下文章

更新与另一个表的内部连接

oracle数据库:表连接

将预先连接的表与另一个表合并

如何将一个表与另一个表连接,然后计算非空列并将它们按另外两个字段分组?

Oracle中的 UPDATE FROM 解决方法

多次删除新增表后怎么恢复数据 oracle