我已经看到很多答案会在表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来返回表头中的行,这些行在详细信息表中没有相关的行。
任何帮助将不胜感激,否则我将留下表现不佳的更新。
答案 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