Я ищу оператор UPDATE, в котором он обновит только одну повторяющуюся строку, а остальные (повторяющиеся строки) останутся нетронутыми как есть, используя ROWID или что-то еще, или другие элементы для использования в 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) должны оставаться как есть!
Большое спасибо, Вал.
Включая тестовую таблицу и образцы вкладышей, было легче ответить на ваш вопрос. Хороший.


Будет ли это работать для вас:
update duptest
set nonid = 'c'
WHERE ROWID IN (SELECT MIN (ROWID)
FROM duptest
GROUP BY id, nonid)
У меня это сработало даже при повторных запусках.
--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
)
Я думаю, это должно сработать.
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
)
Я знаю, что это не отвечает на ваш первоначальный вопрос, но в вашей таблице нет ключа, и из-за этого возникает проблема, связанная с адресом конкретной строки.
Поэтому я предлагаю - если это позволяет конкретное приложение - добавить ключевой столбец в вашу таблицу (например, 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 на самом деле не является идентификатором) и более переносимым решением, чем использование специфичных для БД версий rowid.
UPDATE duptest
SET nonid = 'c'
WHERE nonid = 'b'
AND rowid = (SELECT min(rowid)
FROM duptest
WHERE nonid = 'b');
Как определить, какой 2, b первый. Без столбца с отметкой времени, по которому можно было бы заказать ... Вы хотели сказать «один» вместо «первый»?