0
votes

Oracle se fondre dans la mise à jour de la correspondance, puis supprimer est en train de supprimer toute la ligne

ci-dessous est la donnée que j'ai. J'ai besoin d'une ligne dupliquée à supprimer, mais à la mise à jour parallien de dernière mise à jour ID utilisateur et dernier timbre de mise à jour.

Il y a 3 autres colonnes ci-dessous, comme une clé primaire unique et la dernière mise à jour HYESTAMP et la dernière mise à jour ID utilisateur. P>  Entrez la description de l'image ici p>

Lors de l'exécution de la requête ci-dessous, il supprimait les 8 lignes au lieu de 4. Je ne suis pas capable d'identifier ce qui ne va pas dans la requête, P>

merge into TestTable tgt
using (select ID,
              Date,AMT,
              Currency,
              Value,
              count(*) over (partition by ID, Date, AMT,Currency,Value ) grp_count,
              row_number() over (partition by ID, Date, AMT,Currency,Value order by ID) rn
     from TestTable 
)src
--      where rn > 1) src
on (tgt.ID = src.ID  and src.rn = 2) 
when matched then
    update set  tgt.LastUpdtUser= 'testing',tgt.LastUpdateTime = SYSDATE
    where src.rn = 2
    delete where src.rn = 2;    


3 commentaires

Votre mise à jour ne devrait-elle pas être où src.rn = 1 ?


Oui, il a été modifié quand je collais ici, mais le point est supprimé ne se produit pas ici. Son élimination des 8 rangées quand il ne devrait que supprimer 4.


Mais (tgt.id = src.id et src.rn = 2) empêchera les lignes avec rn = 1 à sélectionner et donc être candidats à la mise à jour, non?


3 Réponses :


1
votes

basé sur ce que vous demandez

Il semble que vous souhaitiez supprimer des entrées identiques ayant (ID, date, amt, devise, valeur)

Si tel est le cas, vous pouvez utiliser la suppression Dupliquer comme suit xxx

voici le lien dbfiddle avec un exemple complet.

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=572C0AAB871A67DA16099


1 commentaires

Dans la requête de fusion, il supprime tout, puisque la condition que vous avez des correspondances spécifiées avec toutes les lignes -> sur (tgt.id = src.id et src.id = 2). Vous dites ici correspondre à tous les enregistrements de TGT, dont l'ID correspond à la SRC_Block qui a RN = 2. Et puisque toutes vos lignes ont des entrées en double, il y a toujours un enregistrement avec RN = 2 pour chacun de la clause partitionnée



0
votes

Voici une solution alternative:

delete from testtable 
where rowid in (    
    SELECT rowid FROM testtable a
WHERE rowid > ANY
(SELECT rowid FROM testtable b
WHERE a.id = b.id
));


0 commentaires

0
votes

On dirait que vous essayez d'éliminer les lignes en double, tout en mettant à jour la rangée restante.

Voici comment je le ferais: P>

MERGE INTO testtable tgt
  USING (SELECT ROWID r_id,
                ID,
                dt,
                amt,
                currency,
                VALUE,
                COUNT(*) OVER (PARTITION BY ID, dt, amt, currency, VALUE) grp_count,
                row_number() OVER (PARTITION BY ID, dt, amt, currency, VALUE ORDER BY lastupdttime) rn
         FROM   testtable) src
  ON (tgt.rowid = src.r_id and src.grp_count > 1)
WHEN MATCHED THEN
  UPDATE SET tgt.lastupdtuser = 'z',
             tgt.lastupdttime = SYSDATE
  DELETE WHERE src.rn > 1;


0 commentaires