2008-10-28 6 views
11

Я ищу инструкцию UPDATE, в которой он будет обновлять только одну повторяющуюся строку и оставаться остальной (повторяющиеся строки) целыми как есть, используя ROWID или что-то еще или другие элементы для использования в Oracle SQL или PL/SQL?Оператор UPDATE в Oracle с использованием SQL или PL/SQL для обновления первой повторяющейся строки ТОЛЬКО

Ниже приведен пример duptest таблицы для работы с:

CREATE TABLE duptest (ID VARCHAR2(5), NONID VARCHAR2(5)); 
  • перспективе один INSERT INTO duptest VALUES('1','a');

  • пробег четыре (4) раза INSERT INTO duptest VALUES('2','b');

Кроме того, первый повторяющаяся строка должна обновляться (не удаляться), всегда, тогда как вторая три (3) должны быть оставлены как есть!

Большое спасибо, Val.

+1

Как вы определяете, какие 2, b является первым. Без столбца timestamp, который вы могли бы заказать ... Вы имели в виду сказать «один» вместо «первым»? – 2008-10-28 20:34:25

ответ

15

Будет ли эта работа для вас:

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

Это работает для меня, даже для повторных запусков.

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

Я думаю, что это должно сработать.

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

Я знаю, что это не отвечает на первый вопрос, но нет ключа на ваш стол и проблемах вы адресацию к конкретным результатам строки из этого.

Так что мое предложение - если конкретное приложение разрешает это - было бы добавить ключевой столбец в вашу таблицу (например, REAL_ID как INTEGER).

Тогда вы могли бы узнать самый низкий идентификатор для дублей

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

и обновлять только эти строки:

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

Я уверен, что оператор обновления может быть настроена несколько, но я надеюсь, это иллюстрирует эту идею.

Преимущество - «более чистый» дизайн (ваш столбец id на самом деле не является идентификатором) и более портативное решение, чем использование конкретных версий DBid.

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