使用其他列中的值更新列

时间:2009-08-25 22:05:55

标签: sql oracle join sql-update

我有一张这样的表:

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 null值,我有一个约束(我无法删除)

感谢目前为止提供的帮助

6 个答案:

答案 0 :(得分:3)

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

  1. foo中存在行中没有匹配行的行。
  2. bar中的匹配行的bar.x为null。
  3. 如果满足上述任一条件,则以下内容将排除对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);
    

答案 1 :(得分:2)

这失败/旋转:

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

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

答案 2 :(得分:1)

  

更新foo set b =(select distinct(   x)来自bar,其中bar.y = foo.b)

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

答案 3 :(得分:1)

在您提供的查询中,您似乎有拼写错误。在您的过程代码中,您修改了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}

答案 4 :(得分:1)

假设您有以下值。

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

上面给出的答案引起了ORA-01427错误。声明需要一些补充,这取决于预期的结果 如果您希望最大的条(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,roworder是不可预测的。 rownum&lt; 2 只接受子选择的第一行。

答案 5 :(得分:0)

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

更新foo set b = x from bar,其中bar.y = foo.b

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