SQL:如果table_1.column_a = table_2.column_a,则更新table_1.column_b

时间:2014-11-13 02:53:35

标签: sql oracle

我有两张这样的桌子。我想更新table_1.column_b 如果 table_1.column_a = table_2.column_a

TABLE_1

column_a   | column_b
----------------------------
   X1       |    0    
   X2       |    0    
   X3       |    0    
   X4       |    0    
   X5       |    0    

TABLE_2

column_a
--------
   X1
   X2
   X3

结果应该是:

TABLE_1

column_a   | column_b
----------------------------
   X1       |    1    
   X2       |    1    
   X3       |    1    
   X4       |    0    
   X5       |    0    

2 个答案:

答案 0 :(得分:1)

update table_1
set column_b = 
(
select count(*) 
from table_2 s
where table_1.column_a = s.column_a
)
/* oracle can bug out when a subquery returns nothing, i.e. Null */
where exists 
(
select 1 
from table_2 s
where table_1.column_a = s.column_a
)
;

有关存在的选择1的额外信息。这只是我倾向于添加的内容,以防万一。这是防御性的编程。

不完全确定需要它,在这种特殊情况下,因为我假设count(*)子查询将为上面表a中的X4和X5条目返回0。

假设您正在这样做...(选择中的1不是真正的下面并不重要,如果你有一个,它可以是table_2中的任何数字或数字列)。重要的是我们这次没有进行计数(*)因此X4和X5不会从table_2中得到任何东西。

update table_1
set column_b = 
(select 1
     from table_2 s
     where table_1.column_a = s.column_a
)

在这种情况下,X4和X5将不会获得子查询结果,Oracle将尝试为table_1.column_b为这些行分配null。 如果该列设置为NOT NULL,则会出现错误。

通过添加查询末尾的where存在,您告诉Oracle不要尝试更新table_1,其中没有匹配的table_2行。所以这个更新null问题永远不会发生。

样板的基本思想是在需要更新列时首先验证更新子查询。然后重复条件作为查询结尾处存在的位置,以避免Oracle在子查询未返回任何内容的情况下尝试更新。

请注意,我可以在where子查询中保留count()。除了我只是寻找匹配行的存在而我实际上并不感兴趣的是计数(),所以我通过要求Oracle选择“更便宜”的结果集来优化一点。

如果您有多个具有不同子查询条件的列更新,那么这将无效。您必须将更新拆分为不同的查询。或者使用Oracle NVL(https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm)来捕获NULL并替换它们。

答案 1 :(得分:0)

这是一种可能的解决方案:

update table_1 a
set    a.column_b = 1
where a.column_a in (select * from table_2);