在Oracle上识别n字段数据表的重复组合

时间:2011-05-09 13:54:40

标签: sql oracle combinations

我设法编写sql查询以将包含组合的重复行更新为2字段表的空值。但是,我坚持使用超过2场的表格。

我的2场解决方案是:

插入组合表的测试数据:

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

从组合'表中,row1和row2是重复的,因为元素的排序无关紧要。

将2个字段的重复组合更新为null(将row2更新为null):

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 --row1
union all
select 2, 1, 3 from dual --row2
union all
select 1, 3, 2 from dual --row3;

具有3个字段的组合2表具有相等的row1,row2,row3。我的目标是将row2和row3更新为null。

1 个答案:

答案 0 :(得分:1)

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步:找到重复项