2008-10-28 7 views
11

Je recherche une instruction UPDATE où elle mettra à jour une seule ligne en double et conservera le reste (lignes en double) intactes tel quel, en utilisant ROWID ou quelque chose d'autre ou d'autres éléments à utiliser dans Oracle SQL ou PL/SQL?instruction UPDATE dans Oracle en utilisant SQL ou PL/SQL pour mettre à jour la première ligne en double SEULEMENT

Voici un exemple de tableau duptest de travailler avec:

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5)); 
  • course d'une INSERT INTO duptest VALUES('1','a');

  • run quatre (4) fois INSERT INTO duptest VALUES('2','b');

En outre, le premier la ligne en double doit être mise à jour (non supprimée), toujours, alors que Trois (3) doivent rester tels quels! Merci beaucoup, Val.

+1

Comment déterminez-vous 2, b est le premier. Sans une colonne d'horodatage que vous pourriez commander par ... Vouliez-vous dire "un" au lieu de "premier"? –

+0

En incluant la table de test et les inserts d'échantillons, il est plus facile de répondre à votre question. Agréable. – JosephStyons

Répondre

15

Est-ce que ce travail pour vous:

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

Cela a fonctionné pour moi, même pour des courses répétées.

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

Je pense que cela devrait fonctionner.

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

Je sais que cela ne répond pas à votre question initiale, mais il n'y a pas de clé sur votre table et le problème que vous avez un résultat précis adressage de ligne de cela. Donc, ma suggestion - si l'application spécifique le permet - serait d'ajouter une colonne clé à votre table (par exemple REAL_ID comme INTEGER).

Ensuite, vous pouvez trouver l'identifiant le plus bas pour les doublons

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

et mettre à jour seulement ces lignes:

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

Je suis sûr que la déclaration de mise à jour peut être accordé un peu, mais je l'espère il illustre l'idée. L'avantage est une conception "plus propre" (votre colonne id n'est pas vraiment un id), et une solution plus portable que de s'appuyer sur les versions spécifiques de DB de rowid.

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