2008-10-28 67 views
11

Estoy buscando una instrucción UPDATE donde actualizará solo una única fila duplicada y permanecerá el resto (filas duplicadas) intacto como está, usando ROWID u otra cosa u otros elementos para utilizar en Oracle SQL o PL/SQL?instrucción UPDATE en Oracle utilizando SQL o PL/SQL para actualizar la primera fila duplicada SOLAMENTE

Aquí es un ejemplo de tabla duptest trabajar con:

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5)); 
  • carrera de una INSERT INTO duptest VALUES('1','a');

  • funcionamiento de cuatro (4) veces INSERT INTO duptest VALUES('2','b');

Además, la primera la fila duplicada debe actualizarse (no eliminarse), siempre, mientras que la otra er tres (3) deben permanecer como están!

Muchas gracias, Val.

+1

¿Cómo se determina qué 2, b es el primero. Sin una columna de marca de tiempo que podría ordenar por ... ¿Quiso decir "uno" en lugar de "primero"? –

+0

La inclusión de la tabla de prueba y los insertos de muestras facilitaron la respuesta a su pregunta. Bonito. – JosephStyons

Respuesta

15

¿Funcionará para usted:

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

Esto funcionó para mí, incluso para distintas ejecuciones.

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

Creo que esto debería funcionar.

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

sé que esto no responde a su pregunta inicial, pero no hay ninguna tecla en su mesa y el problema que ha adressing unos resultados específicos fila de eso.

Así que mi sugerencia, si la aplicación específica lo permite, sería agregar una columna clave a su tabla (por ejemplo, REAL_ID como INTEGER).

Posteriormente, se podría averiguar el ID más bajo para los duplicados

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

y actualizar sólo estas filas:

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

Estoy seguro de que la instrucción de actualización se puede afinar un poco, pero espero ilustra la idea

La ventaja es un diseño "más limpio" (su columna de identificación no es realmente una identificación), y una solución más portátil que confiar en las versiones DB específicas de rowid.

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