[英]Oracle, update column in table 1, when related row does not exist in table 2
我已经看到了许多答案,当表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,但是我无法将其插入到update语句中以提供相同的结果。 选择语句是
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来返回表头中的行,而这些行将在明细表中不包含相关行,从而更新返回的行。
任何帮助将不胜感激,否则我将留下表现不佳的更新。
由于您期望多个标头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')
我不会将条件放在子查询的外部表中。 我更愿意将此逻辑编写为:
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)
和帮助上建立索引。
通常,在我看过的下一个地方,我找到了答案...
update header set status='Z' where not exists (select detail.headerid from detail where detail.headerid = header.id) and status = 'A'
哦,好吧,如果有人要找到它,至少是在这里。
由于错误状态,您的子查询返回了多行,并且您在更新查询中使用=符号。 如果您的查询返回多个记录,则不允许使用=符号,请根据需要使用IN,NOT IN,EXISTS或NOT EXISTS
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.