Напишите запрос, чтобы избавиться от дубликатов записей в базе данных оракула по нижеуказанным критериям:

0

Критерии: 1) уникальная комбинация из 2 столбцов (столбец 1, столбец 2)

2) сохранить самую старую из этой комбинации

3) записи могут быть одинаковыми, то же самое столбец1, столбец2 и дата создания в этом случае нуждаются в том, который имеет меньший идентификатор.

например, данные:

ID      column1     column2     creation_date(dd-mm-yyyy)       
1       11          aa          10/5/2016
2       11          aa          11/6/2016
3       12          bb          10/5/2017
4       12          bb          20-05-2017
5       12          cc          10/5/2016
6       12          cc          11/5/2017
7       13          dd          10/1/2018
8       13          dd          10/1/2018

Мне нужно вести учет с id: 1,3,5,7

Подход, о котором я думаю, таков:

a) сначала напишите запрос выбора, чтобы получить требуемые записи (в этом примере 1,3,5,7)

б) написать запрос обновления для изменения статуса для удаления с помощью запроса на обновление (мягкое удаление)

Также, пожалуйста, предложите, если любой другой лучший подход к выполнению критериев.

Дополнительная информация: * общее количество записей: 11k

* Я не хочу получать записи непосредственно из таблицы, а не у меня есть запрос, который извлекает только требуемые данные, нужно запускать запрос по этим записям

* Конечная цель - изменить статус дубликатов записей для удаления и добавить удаленное слово к этим записям

Теги:
select
sql-update
duplicates

2 ответа

0
Лучший ответ

Это действительно прямо, если вы используете аналитические функции. Запрос состоит из трех частей:

A) Назначьте ранг каждой записи следующим образом: Группируйте записи по столбцам1 и столбцу2. В каждой группе сортируйте записи сначала с помощью create_date, а затем по ID. Назначьте 1 первой записи, 2 - второй и так далее.

B) Храните только дубликаты, т.е. Записи с более новыми параметрами create_date и/или ID. Запись с rnk = 1 будет вашей запрошенной записью. Записи с rnk> 1 - это дубликаты.

C) Используя ROWID, удалите дубликаты

delete
  from your_table
 where rowid in(-- (C) 
        select duplicate_rowid
          from (select rowid as duplicate_rowid
                      ,row_number() over( -- (A) 
                         partition by column1, column2    -- Your criterion 1
                             order by creation_date asc   -- Your criterion 2
                                     ,id            asc   -- Your criterion 3
                      ) as rnk
                  from your_table
                )
         where rnk > 1  -- (B) 
       );
  • 1
    Спасибо за быстрый ответ, все работает нормально. Но сейчас вместо «my_table» я хочу использовать другой запрос, который дает мне только нужные записи из «my_table». Когда я попытался использовать запрос вместо my_table, он не работал. Обратите внимание: общее количество записей составляет 11 КБ, и мой запрос дает мне 8 КБ записей, для которых я хочу выполнить обновление, изменив статус на «удаленный».
  • 0
    Также можно ли использовать блок PL-SQL для зацикливания результата запроса? в качестве конечной цели обновить дубликаты записей с удаленным статусом. или любой другой способ добиться этого. Если да, пожалуйста, предложите.
Показать ещё 6 комментариев
0

Таким образом, окончательные запросы, которые работали на мой вопрос, были следующими:

1), чтобы получить количество записей/для получения необходимых столбцов:

SELECT --count (*) -use this to get count of records
ID, COLUMN1, COLUMN2,CREATION_DATE --required columns
FROM
MY_TABLE
WHERE
ROWID IN( 
        select duplicate_rowid 
          from (select rowid as duplicate_rowid
                      ,row_number() over(  
                         partition by COLUMN1, COLUMN2      --  criterion 1
                             ORDER BY CREATION_DATE ASC   -- criterion 2
                                     ,ID   ASC          -- criterion 3

                      ) AS RNK
                  from MY_TABLE
                )
         WHERE (RNK > 1 and COLUMN1 IS NOT NULL and COLUMN2 IS NOT NULL)
);

2) обновить записи со статусом = удалено и добавить значение _deleted word to column1:

    UPDATE MY_TABLE
    SET STATUS='deleted' , COLUMN1=CONCAT(COLUMN1,'_deleted') 
    WHERE
    ROWID IN( 
                select duplicate_rowid 
                  from (select rowid as duplicate_rowid
                              ,row_number() over(  
                                 partition by COLUMN1, COLUMN2      --  criterion 1
                                     ORDER BY CREATION_DATE ASC   -- criterion 2
                                             ,ID   ASC          -- criterion 3

                              ) AS RNK
                          from MY_TABLE
                        )
                 WHERE (RNK > 1 and COLUMN1 IS NOT NULL and COLUMN2 IS NOT NULL)
);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню