【问题标题】:Update rows in one table with data from another table based on one column in each being equal使用另一个表中的数据更新一个表中的行,基于每个列中的一列相等
【发布时间】:2011-12-16 15:35:17
【问题描述】:

更新许多行到一个表中基于每个列中的一列相等(user_id)。

两个表都有一个user_id 列。当user_id 列相等时,需要将t2 中的数据插入t1

提前感谢您提供的任何帮助。

【问题讨论】:

标签: sql oracle sql-update


【解决方案1】:
update 
  table1 t1
set
  (
    t1.column1, 
    t1.column2
      ) = (
    select
      t2.column1, 
      t2.column2
    from
      table2  t2
    where
      t2.column1 = t1.column1
     )
    where exists (
      select 
        null
      from 
        table2 t2
      where 
        t2.column1 = t1.column1
      );

或者这个(如果 t2.column1 t1.column1 是多对一并且其中任何一个都是好的):

update 
  table1 t1
set
  (
    t1.column1, 
    t1.column2
      ) = (
    select
      t2.column1, 
      t2.column2
    from
      table2  t2
    where
      t2.column1 = t1.column1
    and
      rownum = 1    
     )
    where exists (
      select 
        null
      from 
        table2 t2
      where 
        t2.column1 = t1.column1
      ); 

【讨论】:

  • 非常感谢。在纠正数据以消除重复后就像一个魅力!!!
  • 在 SO 的其他地方还有很多其他答案,但这是唯一对我有用的答案,它救了我的培根。谢谢!
  • 这个答案更新了比需要更多的行。需要额外的where。请参阅 Tony Andrews 的回答。
  • @AlikElzin-kilaka,已更正,感谢指出错误!
【解决方案2】:
merge into t2 t2 
using (select * from t1) t1
on (t2.user_id = t1.user_id)
when matched then update
set
   t2.c1 = t1.c1
,  t2.c2 = t1.c2

【讨论】:

    【解决方案3】:

    你总是可以使用和省略“当不匹配部分”

    merge into table1 FromTable   
       using table2 ToTable
         on     ( FromTable.field1 = ToTable.field1
              and  FromTable.field2 =ToTable.field2)
    when Matched then
    update set 
      ToTable.fieldr = FromTable.fieldx,
      ToTable.fields = FromTable.fieldy, 
      ToTable.fieldt =  FromTable.fieldz)
    when not matched then
      insert  (ToTable.field1,
           ToTable.field2,
           ToTable.fieldr,
           ToTable.fields,
           ToTable.fieldt)
      values (FromTable.field1,
             FromTable.field2,
             FromTable.fieldx,
             FromTable.fieldy,
             FromTable.fieldz);
    

    【讨论】:

      【解决方案4】:

      如果记录已存在于 t1 中(user_id 匹配),则不是插入,除非您乐于创建重复的 user_id。

      您可能想要更新?

      UPDATE t1
         SET <t1.col_list> = (SELECT <t2.col_list>
                                FROM t2
                               WHERE t2.user_id = t1.user_id)
       WHERE EXISTS
            (SELECT 1
               FROM t2
              WHERE t1.user_id = t2.user_id);
      

      希望对你有帮助...

      【讨论】:

      • ORA-01427: 单行子查询返回多行
      • 我不断返回相同的 ora 01427 单行查询返回多行。
      • 如果关系不是一对一的,你会得到一个 ORA-01427 错误。这意味着您的 equijoin 语句无法成功地将表一中的一条记录与表二中的一条记录匹配。
      【解决方案5】:

      如果您想用 t2 中的数据更新 t1 中的匹配行,则:

      update t1
      set (c1, c2, c3) = 
      (select c1, c2, c3 from t2
       where t2.user_id = t1.user_id)
      where exists
      (select * from t2
       where t2.user_id = t1.user_id)
      

      “where exists”部分是为了防止在不存在匹配项的情况下将 t1 列更新为 null。

      【讨论】:

      • 谢谢。像我尝试过的其他查询一样,这会返回“单行查询 rturns many rows”。不会插入/更新任何东西。
      • 所以 user_id 在 t1 中不是唯一的?在这种情况下,您怎么知道从 哪个 t1 获取值?
      • 是的,每个user_id只有一个。两个表都有一列 user_id 并且有匹配的条目,但是每个用户只有一个 user_id....
      • “单行查询返回多行”错误意味着对于某些 user_id,t2 中有 2 行(或更多行)。所以要么你最后的评论是错误的,要么你的数据库已经损坏了!
      • 谢谢......应该只有一个......我应该说我会更仔细地看。我非常感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2012-11-08
      • 2016-12-01
      • 1970-01-01
      相关资源
      最近更新 更多