2016-08-20 10 views
0

Ich verwende die folgenden 3 Abfragen, um den Status basierend auf dem Wert von 3 verschiedenen Spalten aus einer anderen Tabelle zu aktualisieren.Aktualisierung derselben Spalte aus anderen Spalten einer anderen Tabelle

UPDATE NUMBER_TABLE SET STATUS='X' WHERE STATUS='P' AND NUMBER IN 
      (SELECT NVL(CONTACT_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P'); 

UPDATE NUMBER_TABLE SET STATUS='X' WHERE STATUS='P' AND NUMBER IN 
      (SELECT NVL(HOME_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P'); 

UPDATE NUMBER_TABLE SET STATUS='X' WHERE STATUS='P' AND NUMBER IN 
      (SELECT NVL(WORK_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P'); 

Alle 3 Abfragen führen einen vollständigen Tabellenscan durch. Kann jemand einen besseren Weg der Zusammenführung von 3 Abfragen in einer

+0

Gibt es tatsächlich Zeilen in 'NUMBER_TABLE' wo' NUMBER' ist ' 'XXXXXXXXXX''? –

Antwort

1

So etwas wie dies funktioniert.

HINWEIS: Sie haben gesagt, dass Sie diese drei Abfragen zum Aktualisieren verwenden ... Das stimmt nicht. Ihre Abfragen würden nicht wie geschrieben funktionieren; NUMBER ist ein reserviertes Oracle-Schlüsselwort, sodass Sie Kompilierungsfehler erhalten. Wenn du etwas postest, sei bitte sehr vorsichtig, was du sagst. Die Abfrage, die ich unten als Lösung anbiete, wird aus dem gleichen Grund auch nicht funktionieren. Verwenden Sie Ihre tatsächlichen Spaltennamen.

UPDATE NUMBER_TABLE n SET STATUS='X' WHERE STATUS='P' AND EXISTS 
    (SELECT 1 FROM TMP_NUMBER_FOUND t where n.NUMBER = NVL(t.CONTACT_NO, 'XXXXXXXXXX') 
             or n.NUMBER = NVL(t.HOME_NO , 'XXXXXXXXXX') 
             or n.NUMBER = NVL(t.WORK_NO , 'XXXXXXXXXX') 
    ) 
; 

Added basierend auf weitere Informationen von OP (siehe Kommentar).

Das OP teilte die Information, dass in seinen Daten keine Zahlen gleich 'XXXXXXXXXX' sind. In diesem Fall ist die NVL(...) unnötig und verschwendet nur Zeit. Vergleichen mit 'XXXXXXXXXX' in diesem Fall wird der gleiche sein wie im Vergleich zu NULL, da im Vergleich zu NULL nie TRUE zurückgibt. Also: entfernen diejenigen NVL Wrapper, sie sind eine große Quelle der Langsamkeit.

mit einem anderen Dies wird kommen, noch mehr Nutzen: die Spalten CONTACT_NO, HOME_NO und WORK_NO sollten, wenn sie es nicht schon sind indiziert werden, und wenn sie von NVL(...) nicht umgeben sind, können die Indizes tatsächlich verwendet werden. Es sollte auch einen Index für NUMBER geben. Das OP sagte, dass diese Spalte Teil der PK ist, aber nicht die erste Spalte in der PK, und fragte, ob er es zur ersten Spalte machen sollte. Die Antwort ist JA - oder, wenn es einen guten Grund gibt, dass eine andere Spalte zuerst bleiben sollte (vielleicht verlassen sich andere Abfragen darauf), dann sollte NUMBER seinen eigenen Index bekommen. Aber wenn es die erste Spalte in der PK gemacht werden kann, sollte das ausreichen.

+0

Danke für die Lösung. kann ich irgendeine Art von Hinweis auf diese Abfrage verwenden, um sie schneller zu machen. – Ashish

+0

Nicht sicher (normalerweise nicht). Haben Sie einen Index für die Spalte "NUMBER_TABLE.NUMBER"? Auch das NVL-Material nimmt wahrscheinlich viel Zeit in Anspruch - haben Sie viele "Zahlen" in der Tabelle "NUMBER_TABLE" mit einem "NUMBER" -Wert von "XXXXXXXXXX"? – mathguy

+0

In TMP_NUMBER_FOUND kann CONTACT_NO usw. NULL sein. Aus diesem Grund habe ich NVL verwendet, um NULL-Spalten herauszufiltern. Ich habe XXXXXXXXXX nicht. NUMBER_TABLE.NUMBER ist ein Teil von PK, aber es ist die zweite Spalte von PK. Wird es die erste Hilfe sein? – Ashish

0

vorschlagen sollte ich vorschlagen

UPDATE number_table n INNER JOIN tmp_number_found t 
           ON n.number = NVL(t.contact_no, 'XXXXXXXXXX') 
           OR n.number = NVL(t.home_no, 'XXXXXXXXXX') 
           OR n.number = NVL(t.work_no, 'XXXXXXXXXX') 
    SET n.status='X' 
WHERE n.status='P' 
    AND t.status='P' 
; 
+0

Es hat nicht funktioniert. Fehler ORA - 00971 fehlt SET Schlüsselwort – Ashish

1

Sie CASE mit Update verwenden können,

UPDATE NUMBER_TABLE SET STATUS=(CASE when NUMBER IN 
      (SELECT NVL(CONTACT_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X' 
      when NUMBER IN 
      (SELECT NVL(HOME_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X' 
       WHEN NUMBER IN 
      (SELECT NVL(WORK_NO,'XXXXXXXXXX') FROM TMP_NUMBER_FOUND WHERE STATUS='P') AND STATUS='P' then 'X' ELSE STATUS END); 
+0

Diese Abfrage setzt den Status für Mached-Zeilen auf "X", aber der Status auf NULL für das Beenden von "P" Wert – Ashish

+0

hat Ihren zweiten Teil des Problems nicht betroffen. –

Verwandte Themen