更新列并立即使用结果更新同一语句中的第二列

Posted

技术标签:

【中文标题】更新列并立即使用结果更新同一语句中的第二列【英文标题】:Update column and instantly use result to update second column within same statement 【发布时间】:2020-01-16 13:43:25 【问题描述】:

在 Oracle SQL(版本 12c)中,有没有一种方法可以对相互引用的多个列执行更新?假设我有一个名为 test_tb 的表:

|pk  |col1|col2|
----------------
|1   |4   |1   |
|2   |9   |2   |
|3   |7   |9   |

我打算达到以下结果:

|pk  |col1|col2|
----------------
|1   |5   |6   |
|2   |10  |12  |
|3   |8   |17  |

通过第一次设置

col1 = col1 + 1

紧随其后

col2 = col2 + col1

据我所知,我可以这样做:

update test_tb set col1 = col1 + 1, col2 = col2 + col1 + 1

但是,当进行更复杂的操作时,这将变得很容易维护。另一种选择是:

merge into test_tb desc
using (
  with tmp as (
    select pk,
      col1 + 1 as col1,
      col2
    from test_tb
  )
  select pk,
    col1,
    col2 + col1 as col2
) src
on (dest.pk = src.pk)
when matched then update set
  dest.col1 = src.col1,
  dest.col2 = src.col1;

有大量数据(我的表有大约 10 mio. 行),这不是性能明智的选择。

有没有什么办法可以不用写两次导致"col1"的代码,同时也有很好的性能?

【问题讨论】:

您打算多久执行一次此操作?用 COL1 的更新值更新 COL2 听起来像是一个非常奇怪的数据模型。我很想知道业务逻辑到底是什么。 【参考方案1】:

也许您可以更新内联视图?例如:

update (select pk,
               col1,
               col2,
               col1 + 1 col1_new
        from   your_table)
set col1 = col1_new,
    col2 = col2 + col1_new;

Full test case

【讨论】:

太好了,这行得通!碰巧:您是否还知道是否有办法额外并行化它?我已经尝试在 ( 之前的更新之后以及在 pk 之前的 select 之后添加 /*+ 并行 */ 提示。 我想您需要在dbfiddle.uk/… 中执行更新之类的操作 - 即为子查询设置别名并在并行提示中引用该别名。

以上是关于更新列并立即使用结果更新同一语句中的第二列的主要内容,如果未能解决你的问题,请参考以下文章

合并第二列到最后一列以获取第一列中的重复项

WPF DataGrid在同一列中的不同控件 - 不正确的绑定

根据另一列中的行自动填充第二列中的数据

如何使用 flexbox 对齐第二列中的内容?

如何在插入新行后立即将自动生成的主键值保存到第二列

如何将第二列中的文本居中到页面 - 引导