2008-10-28 10 views
11

Ich bin auf der Suche nach einer UPDATE-Anweisung, wo es nur eine einzige doppelte Zeile aktualisiert wird und den Rest (doppelte Zeilen) intakt bleiben wird, mit ROWID oder etwas anderes oder andere Elemente in Oracle SQL oder PL/SQL zu verwenden?UPDATE-Anweisung in Oracle mit SQL oder PL/SQL zu aktualisieren erste NUR doppelte Zeile

Hier ist ein Beispiel duptest Tabelle mit arbeiten:

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5)); 
  • geführten INSERT INTO duptest VALUES('1','a');

  • Laufe von vier (4) mal INSERT INTO duptest VALUES('2','b');

Auch die ersten doppelte Zeile muss immer aktualisiert werden (nicht gelöscht), während die anderen drei (3) müssen so bleiben wie es ist!

Vielen Dank, Val.

+1

Wie bestimmen Sie, welche 2, b ist zuerst. Ohne eine Zeitstempelspalte, die Sie bestellen könnten ... Meinen Sie "eins" statt "zuerst" sagen? –

+0

Mit der Testtabelle und den Probeneinsätzen konnten Sie Ihre Frage leichter beantworten. Nett. – JosephStyons

Antwort

15

Wird diese Arbeit für Sie:

update duptest 
set nonid = 'c' 
WHERE ROWID IN (SELECT MIN (ROWID) 
           FROM duptest 
          GROUP BY id, nonid) 
1

Das ist für mich gearbeitet, auch bei wiederholten Läufen.

--third, update the one row 
UPDATE DUPTEST DT 
SET DT.NONID = 'c' 
WHERE (DT.ID,DT.ROWID) IN(
         --second, find the row id of the first dup 
         SELECT 
          DT.ID 
          ,MIN(DT.ROWID) AS FIRST_ROW_ID 
         FROM DUPTEST DT 
         WHERE ID IN(
            --first, find the dups 
            SELECT ID 
            FROM DUPTEST 
            GROUP BY ID 
            HAVING COUNT(*) > 1 
            ) 
         GROUP BY 
          DT.ID 
         ) 
1

Ich denke, das sollte funktionieren.

UPDATE DUPTEST SET NONID = 'C' 
WHERE ROWID in (
    Select ROWID from (
     SELECT ROWID, Row_Number() over (Partition By ID, NONID order by ID) rn 
    ) WHERE rn = 1 
) 
0

Ich weiß, dass dies nicht Ihre erste Frage nicht beantworten, aber es gibt keinen Schlüssel auf dem Tisch und das Problem, das Sie haben eine bestimmte Zeile ergibt sich aus, dass praxisnah erläutert.

Also mein Vorschlag - wenn die spezifische Anwendung es erlaubt - wäre, eine Schlüsselspalte zu Ihrer Tabelle hinzuzufügen (z.B. REAL_ID als INTEGER).

Dann könnten Sie die niedrigste ID für die Duplikate

select min (real_id) 
from duptest 
group by (id, nonid) 

und aktualisieren finden Sie heraus, diese Zeilen:

update duptest 
set nonid = 'C' 
where real_id in (<select from above>) 

Ich bin sicher, dass die Update-Anweisung etwas abgestimmt werden kann, aber ich hoffe, es illustriert die Idee.

Der Vorteil ist ein "sauberer" Entwurf (Ihre ID-Spalte ist nicht wirklich eine ID), und eine portablere Lösung, als sich auf die DB-spezifischen Versionen von Rowid zu verlassen.

1
UPDATE duptest 
SET  nonid = 'c' 
WHERE nonid = 'b' 
    AND rowid = (SELECT min(rowid) 
       FROM duptest 
       WHERE nonid = 'b');