【问题标题】:Left join update statement左连接更新语句
【发布时间】:2018-10-17 13:45:59
【问题描述】:

我找不到任何容易使用左连接的值进行表更新的方法。 我想做这样的事情:

UPDATE tbl1 p
LEFT JOIN (
select column1 , column2 from tbl2
union
select column1,column2 from tbl3
) c on c.column2=p.column2
SET p.column1 =  nvl(c.column1, 'dummy');

【问题讨论】:

    标签: sql oracle join sql-update


    【解决方案1】:
    UPDATE p SET p.column1 =  nvl(c.column1, 'dummy')
    from tbl1 p
    LEFT JOIN (
    select column1 , column2 from tbl2
    union
    select column1,column2 from tbl3
    ) c on c.column2=p.column2
    

    【讨论】:

      【解决方案2】:

      我建议将其表达为:

      UPDATE tbl1 p
          SET p.column1 =  COALESCE((SELECT column1 from tbl2 t2 WHERE t2.column2 = p.column2),
                                    (SELECT column1 from tbl3 t3 WHERE t3.column2 = p.column2),
                                    'dummy'
                                   );
      

      每个子查询都可以使用索引,所以这也应该有更好的性能。

      【讨论】:

        【解决方案3】:

        试试看下面的代码是否能提供 CTE 的性能

        Update tbl1 p
        set column1 =  nvl((with CTE as 
        (select column1 , column2 from tbl2
        union
        select column1,column2 from tbl3) select column1 from CTE where CTE.column2= p.column2  ),'dummy');
        

        【讨论】:

          【解决方案4】:

          使用merge:

          merge into tbl1 tgt
          using (select min(column1) column1, column2
                   from (select column1, column2 from tbl2 union all
                         select column1, column2 from tbl3)
                   group by column2) src
          on (tgt.column2 = src.column2)
          when matched then update set tgt.column1 = src.column1
          

          假设您有这些表:

          create table tbl1(column1, column2) as (
              select 0, 'A' from dual union all
              select 0, 'B' from dual union all
              select 0, 'C' from dual union all
              select 0, 'D' from dual );
          
          create table tbl2(column1, column2) as (
              select  1, 'A' from dual union all
              select 41, 'D' from dual );  
          
          create table tbl3(column1, column2) as (
              select  2, 'B' from dual union all
              select 42, 'D' from dual );  
          

          我们在tbl2 中具有键A 的值,在tbl3 中具有B 的值,C 的值在两个源表中都不存在,并且键D 有两个有问题的值。您必须决定在最后一种情况下要做什么,对字符串使用任何聚合函数,如 min()avg()listagg()。如果这种情况不可能,那么您可以简化我的语句,用简单的联合替换源子查询。

          您也可以使用update,但在这种情况下,您必须添加where 子句并检查键的存在以避免使值无效,这会使代码更长。

          merge:的结果

             COLUMN1  COLUMN2
          ----------  -------
                   1  A
                   2  B
                   0  C
                  41  D
          

          【讨论】:

            【解决方案5】:

            如果可以在 WHEN MATCHED 和 WHEN NOT MATCHED 中更新相同的字段,Merge 语句可能是完美的解决方案。无论如何,我这样修复它: 该表正在使用过程从外部表中填充。 将过程插入语句中的所有记录的字段设置为“虚拟”,并在我预期的工作后仅使用 MERGE WHEN MATCHED

            PS:我无法让它像@Ondřej Crha 所说的那样工作。

            【讨论】:

              猜你喜欢
              • 2011-09-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多