【问题标题】:Update column with values from another column使用另一列中的值更新列
【发布时间】:2010-11-22 19:26:47
【问题描述】:

我有一张这样的桌子:

create table foo ( a number, b number ) 

我想用另一个表中的值更新 a 中的所有列

create table bar ( x number, y number ) 

所以,如果这是一种过程式编程语言,我会:

 foreach foo_item in foo 
     foreach bar_item in bar 
         if( foo_item.b == bar_item.y ) 
             foo_item.a = bar_item.x 
         end
     end
 end

我试过了

update foo 
set a = ( select distinct( x ) from bar where bar.y = foo.b ) 

但它挂了.... 我不太确定如何做这样的事情(甚至不知道谷歌是为了什么)

谢谢

编辑对不起,我的错。它没有挂起,但它尝试设置 va 空值并且我有一个约束(我无法删除)

感谢到目前为止的帮助

【问题讨论】:

  • @GApple,不,foo.b和bar.y的重复值很多

标签: sql oracle join sql-update


【解决方案1】:

尝试将 foo.a 更新为 NULL 有两个可能的原因。

  1. 存在 foo 中的行,而 bar 中没有与之匹配的行。
  2. bar 中的匹配行的 bar.x 为 null。

如果上述任一条件为真,则以下内容将排除对 foo 的更新。在这些情况下 foo.a 将保持原样:

update foo 
set a = (select distinct( x ) from bar where bar.y = foo.b )
where exists 
  (select *
  from bar 
  where bar.y = foo.b
  and bar.x is not null);

【讨论】:

    【解决方案2】:

    这失败/旋转:

    UPDATE foo 
       SET b = (SELECT DISTINCT(x) 
                  FROM bar 
                 WHERE bar.y = foo.b)
    

    ...因为您正在更新要用于确定更新内容的相同值。 Oracle 始终允许用户读取数据。

    【讨论】:

      【解决方案3】:

      update foo set b = (select distinct( x ) 从 bar where bar.y = foo.b )

      出于性能原因可能会挂起,但应该可以工作。仔细检查如果没有 bar.y 等于 foo.b 会发生什么。如果将 b 设置为 null 可以吗?

      【讨论】:

        【解决方案4】:

        在您提供的查询中,您似乎有一个错字。在您的程序代码中,您修改了 foo.a 的值,但您的查询更新了 foo.b:

        update foo set a = ( select distinct( x ) from bar where bar.y = foo.b )
        

        此外,如果 bar.y 有许多行具有相同的值,则可能会出现问题。您的子查询可能会返回一个结果集,而不是您的赋值期望的单个值。 例如,如果您的数据是

        foo(x,y) = [{1,2},{2,2},{3,2}]
        

        那么“DISTINCT x”将返回“{1,2,3}

        【讨论】:

          【解决方案5】:

          假设您有以下值。

          foo(a,b) = [{0,2}]
          bar(x,y) = [{1,2},{2,2},{3,2}]

          上面给出的答案引发了 ORA-01427 错误。该语句需要一些补充,这取决于预期的结果。
          如果您期望最大的 bar(x,2) 应该存储在 foo(a,2) 中。

          foo(a,b) = [{3,2}]
          update foo 
            set a = (select max(x) from bar where bar.y = foo.b  
                     and bar.x is not null)
          where exists 
            (select *
            from bar 
            where bar.y = foo.b
            and bar.x is not null);
          

          如果您期望 bar(x,2) 的任何值而不是写以下内容。

          foo(a,b) = [{[1|2|3],2}]
          update foo 
            set a = (select x from bar where bar.y = foo.b 
                     and bar.x is not null 
                     and rownum < 2)
          where exists 
            (select *
            from bar 
            where bar.y = foo.b
            and bar.x is not null);
          

          子选择的顺序取决于存储和行检索。两个更新都可以给出相同的结果。如果没有 ORDER BY,则行顺序是不可预测的。 rownum 只取子选择的第一行。

          【讨论】:

            【解决方案6】:

            如果您使用的是 MS SQL Server 或 Sybase,您可以使用以下,

            更新 foo set b = x from bar where bar.y = foo.b

            抱歉,我没有看到您使用的是 Oracle。我猜你必须为此创建存储过程。

            【讨论】:

              猜你喜欢
              • 2014-11-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-06-20
              • 1970-01-01
              相关资源
              最近更新 更多