Выявление повторяющихся комбинаций для таблицы данных n-поля в Oracle - PullRequest
2 голосов
/ 09 мая 2011

Мне удалось создать SQL-запрос, чтобы обновить дублирующиеся строки, содержащие комбинации, до нулевого значения для таблицы с 2 полями.Тем не менее, я застрял с более чем 2 поля таблицы.

Мое решение с двумя полями:

Вставка тестовых данных для таблицы комбинаций:

create table combinations as 
select 1 col1, 2 col2 from dual --<i>row1</i> 
union all 
select 2, 1 from dual --<i>row2</i>
union all 
select 1, 3 from dual --<i>row3</i>
union all 
select 1,4 from dual; --<i>row4</i>

Из таблицы комбинаций строки1 и строки2 являютсядубликаты, потому что порядок элементов не имеет значения.

Обновление дублирующихся комбинаций до нуля для 2 полей (обновление строки2 до нуля):

update combinations 
set col1=null, col2=null 
where rowid IN(
select x.rid from (
    select 
        rowid rid, 
        col1, 
        col2, 
        row_number() over (partition by least(col1,col2), greatest(col1,col2)
                               order by rownum) duplicate_row 
    from combinations) x 
where duplicate_row > 1);

Мой код выше зависитпо функциям наименьшего (,) и наибольшего (,), и поэтому он работает аккуратно.Любые идеи по настройке этого кода для таблицы с 3 полями?

Вставка данных испытаний для таблицы комбинаций2 '(3 поля)

create table combinations2 as
select 1 col1, 2 col2, 3 col3 from dual --<i>row1</i>
union all
select 2, 1, 3 from dual --<i>row2</i>
union all
select 1, 3, 2 from dual --<i>row3</i>;

Таблица комбинаций2 с 3-поля имеют строки 1, 2, 2, которые равны.Моя цель - обновить row2 и row3 до нуля.

1 Ответ

1 голос
/ 09 мая 2011
update combinations2
set col1 = NULL
  , col2 = NULL
  , col3 = NULL
where rowid in (
            select r 
            from
                (
                -- STEP 4
                select r, row_number() over(partition by colls order by colls) duplicate_row
                from
                    (
                    -- STEP 3
                    select r, c1 || '_' || c2 || '_' || c3 colls
                    from
                        (
                        -- STEP 2
                        select r
                              , max(case when rn = 1 then val else null end) c1 
                              , max(case when rn = 2 then val else null end) c2
                              , max(case when rn = 3 then val else null end) c3
                        from 
                            (
                            -- STEP 1
                            select r
                                  , val
                                  , row_number() over(partition by r order by val) rn
                            from
                                (
                                  select rowid as r, col1 as val
                                  from combinations2
                                union all
                                  select rowid, col2
                                  from combinations2
                                union all
                                  select rowid, col3
                                  from combinations2
                                )
                            )
                        group by r
                        )
                    )
                )
            where duplicate_row > 1
            )
;
  • шаг 1: сортировка значений в столбцах
  • шаг 2: построение строк с отсортированными значениями
  • шаг 3: объединение столбцов в строку
  • шаг 4: найти дубликаты
...