2016-08-11 5 views
0

Ich habe viele Antworten gesehen, die eine Tabelle 1, wenn Zeilen vorhanden ist in Tabelle 2 aktualisieren, aber nicht eine, die ein LEFT JOIN die bei der Auswahl arbeitet mit Zeilen (für bessere Leistung). Ich habe eine Lösung für das Update, aber es funktioniert schlecht, da es NOT IN verwendet.Oracle, update Spalt in Tabelle 1, wenn im Zusammenhang Reihe existiert nicht in Tabelle 2

Also diese SQL wird die Tabellen wie erforderlich aktualisieren, aber es scheint sehr teuer zu sein, wenn es gegen große Tabellen ausgeführt wird, die es schwierig machen, es zu verwenden.

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

Jetzt habe ich eine gute Leistung Abfrage ein LEFT JOIN mit denen die richtigen IDs zurückgibt, aber ich habe nicht in der Lage gewesen, es in eine Update-Anweisung einzufügen die gleichen Ergebnisse zu geben. Die select-Anweisung ist

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

Also, wenn ich das in der Update-Anweisung verwenden als in:

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' 
) 

Dann mit mir nicht:

ORA-01427: einreihiger Unterabfrage gibt mehr als eine Zeile zurück

Ich erwarte mehrere er ader.id zurückgegeben werden und alle diese Zeilen aktualisieren möchten.

So suche ich immer noch nach einer Lösung, die die zurückgegebenen Zeilen aktualisiert, mit einer gut durchführbaren SQL-Auswahl zum Zurückgeben von Zeilen im Tabellenheader, die keine verwandten Zeilen in der Detailtabelle haben.

sonst würde ich jede mögliche Hilfe geschätzt, mit der schlechten Durchführung Update gelassen werden.

Antwort

0

Da Sie mehrere Header ID & die Unterabfrage gibt mehrere ID erwartet werden, wie Sie erwartet, sollten Sie IN

Versuchen Sie, diese

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

ich nicht die Bedingung setzen würde verwenden, um auf die äußeren Tabelle in der Unterabfrage. Ich bin bequemer schreibt diese Logik wie:

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

Wenn die Leistung ein Problem, Indizes für detail(headerid) und header(status, id) und Hilfe.

0

typisch, ist der nächste Ort, den ich sah, fand ich eine Antwort ...

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

Na ja, zumindest der hier, ob jemand will, es zu finden.

0

Da der Fehler angibt, dass Ihre Unterabfrage mehr als eine Zeile zurückgibt und Sie ein = verwenden, melden Sie sich in Ihrer Aktualisierungsabfrage an. = Zeichen ist nicht erlaubt, wenn Ihre Abfrage mehr als eine Datensätze zurückgibt verwenden entweder IN, NOT IN, EXISTS, VORHANDEN NICHT wie pro Ihre Anforderung

Verwandte Themen