2016-08-11 59 views
0

我見過很多答案,當表2中存在行時會更新表1,但沒有一個在選擇表中存在行時使用LEFT JOIN行(爲了更好的性能)。我有一個更新的解決方案,但它會執行不好,因爲它使用NOT IN。Oracle在表1中更新列時,當表2中不存在相關行時

因此,這個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:單行子查詢返回多行

我期待着他多ader.id被返回並且想要更新所有這些行。

因此,我仍然在尋找一種解決方案,它將更新返回的行,使用性能良好的SQL select來返回表頭中的行,但在詳細信息表中沒有相關的行。

任何幫助,將不勝感激,否則我將留下性能不佳的更新。

回答

0

如你預期,你應該使用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') 
0

我不會把條件對既然你期望多個頭ID &子查詢返回多個ID子查詢中的表。我更舒服寫這個邏輯:

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)和幫助索引。

0

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

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

哦,好吧,至少它在這裏,如果別人想找到它。

0

由於錯誤說明您的子查詢返回多個行,並且您在更新查詢中使用了=符號。 =符號是不允許的,如果您的查詢返回多個記錄使用IN,NOT IN,EXISTS,NOT EXISTS根據您的要求

相關問題