Оператор UPDATE в Oracle с использованием SQL или PL / SQL ТОЛЬКО для обновления первой повторяющейся строки

Я ищу оператор 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) должны оставаться как есть!

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

Как определить, какой 2, b первый. Без столбца с отметкой времени, по которому можно было бы заказать ... Вы хотели сказать «один» вместо «первый»?

Mark Brady 28.10.2008 23:34

Включая тестовую таблицу и образцы вкладышей, было легче ответить на ваш вопрос. Хороший.

JosephStyons 28.10.2008 23:48
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
11
2
81 469
5

Ответы 5

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

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');

Другие вопросы по теме