Oracle,表1中的更新列,表2中不存在相关行

时间:2016-08-11 10:43:19

标签: sql oracle sql-update left-join

我已经看到很多答案会在表2中存在行时更新表1,但是在选择行时使用LEFT JOIN不会更新表(为了更好的性能)。我有一个更新的解决方案,但它会在使用NOT IN时表现不佳。

因此,这个SQL将根据需要更新表,但是当对大表运行时,它看起来非常昂贵,因此难以使用。

update header 
set status='Z' 
where status='A' 
and header.id not in (
    select headerid 
    from detail 
    where detail.id between 0 and 9999999
);

现在我使用LEFT JOIN进行了性能良好的查询,返回正确的ID,但是我无法将其插入到更新语句中以提供相同的结果。 select语句是

select header.id 
from header 
left join detail on detail.headerid = header.id 
where detail.headerid is null 
and header.status='A'

因此,如果我在更新语句中使用它,如:

update header 
set status = 'Z' 
where header.id = (
    select header.id 
    from header 
    left join detail on detail.headerid = header.id 
    where detail.headerid is null and header.status='A'
)

然后我失败了:

  

ORA-01427:单行子查询返回多行

我希望返回多个header.id,并希望更新所有这些行。

所以我仍然在寻找一个解决方案来更新返回的行,使用性能良好的SQL select来返回表头中的行,这些行在详细信息表中没有相关的行。

任何帮助将不胜感激,否则我将留下表现不佳的更新。

4 个答案:

答案 0 :(得分:0)

因为您需要多个标头ID&子查询返回多个ID,因为您应该使用IN

试试这个

Update 
    header 
Set status = 'Z' 
Where 
    header.id IN (select 
                      header.id 
                  From
                      header 
                  Left join 
                      detail 
                  On 
                      detail.headerid = header.id 
                  Where 
                      detail.headerid is null 
                  And 
                      header.status='A')

答案 1 :(得分:0)

我不会将条件放在子查询中的外部表中。我更乐于将这种逻辑写成:

update header h
    set status = 'Z'
    where not exists (select 1
                      from detail d
                      where d.headerid = h.id
                     ) and
          h.status = 'A';

如果效果有问题,请在detail(headerid)header(status, id)以及帮助

上建立索引

答案 2 :(得分:0)

典型的,我看的下一个地方,我找到了答案......

update header set status='Z' where not exists (select detail.headerid from detail where detail.headerid = header.id) and status = 'A'

哦,好吧,至少它在这里,如果有人想找到它。

答案 3 :(得分:0)

由于错误声明您的子查询返回多行,并且您在更新查询中使用了=符号。如果您的查询返回多个记录,则不允许使用符号根据您的要求使用IN,NOT IN,EXISTS,NOT EXISTS