更新重复行的列oracle

Posted

技术标签:

【中文标题】更新重复行的列oracle【英文标题】:Update column of duplicated rows oracle 【发布时间】:2014-07-10 10:57:55 【问题描述】:

我在 oracle 中有一个包含 3 列的表:

create table pruebaBorrado (
 num1 varchar2(24), 
 num2 varchar2(24),
 num3 varchar2(24)); 

表格包含:

insert into pruebaBorrado values ('1','1','1');
insert into pruebaBorrado values ('1','1','1'); 
insert into pruebaBorrado values ('1','1','1');
insert into pruebaBorrado values ('2','2','2');
insert into pruebaBorrado values ('2','2','2'); 
insert into pruebaBorrado values ('3','3','3'); 

如您所见,存在重复的行。我只想为重复的行更改“num3”列并获得以下信息:

'1', '1', '1' 
'1', '1', '1A' 
'1', '1', '1B' 
'2', '2', '2' 
'2', '2', '2A' 
'3', '3', '3'

我怎样才能做到这一点?提前致谢!!

【问题讨论】:

必须用字母改吗? 是的,如果可能的话 【参考方案1】:

这有点蛮力,但确实有效:

update pruebaBorrado
    set num3 = (case (select count(*)
                      from pruebaBorrado pb
                      where pb.num1 = pruebaBorrado.num1 and pb.num2 = pruebaBorrado.num2 and
                            pb.rowid <= pruebaBorrado.rowid
                     )
                 when 1 then num3
                 when 2 then num3 || 'A'
                 when 3 then num3 || 'B'
                 when 4 then num3 || 'C'
                 else num3 || 'X'
                 end
                );

SQL Fiddle 是 here。

编辑:

以下也应该有效:

update pruebaBorrado
    set num3 = num3 ||
               substr(' ABCDEFGHIJKLMNOPQRSTUVWXYZ,
                      (select count(*)
                       from pruebaBorrado pb
                       where pb.num1 = pruebaBorrado.num1 and pb.num2 = pruebaBorrado.num2 and
                             pb.rowid <= pb.rowid
                      ), 1);

【讨论】:

我有这个错误:ORA-00904: "PB"."ROW_ID":invalid identifier @mcl 。 . .一个错字。我在 SQL Fiddle 中更改了它,但没有在答案中更改。 rowid 中没有下划线。 如果你看到你的解决方案,那不是我想要的。请看我的帖子 @mcl 。 . .问题已解决。【参考方案2】:

这行得通,经过测试。我在这里使用了 chr() ,它将 ascii 值转换为 char 以获取 A、B、C .. 和 rank 函数。

update pruebaBorrado pb1
      set num3 = num3 || ( 
             select chr(temp.rank+63)  
            from ( select rowid, rank() over ( partition by num1,num2,num3     order by rowid ) rank 
                   from pruebaborrado pb2 ) temp
             where 
           temp.rowid = pb1.rowid
          and temp.rank >1
); 

逻辑如下:

    Rank 函数将对每个重复的行进行排名,如下所示:

    num1|num2|num3|rank 1| 1| 1 | 1 1| 1| 1 | 2 1| 1| 1 | 3

    在此等级之后,通过向其添加 63 来生成 A、B、C 的 ASCII。使用 63 是因为我们需要为排名为 2 且 A 的 ASCII 值为 65 的第一个副本附加 A。

【讨论】:

以上是关于更新重复行的列oracle的主要内容,如果未能解决你的问题,请参考以下文章

从表中选择不同的记录并执行重复行的列总和(托盘、总和)。并显示重复的行一次[关闭]

将行数传递给Oracle中的列[重复]

Oracle始终获取具有标识的插入行的ID [重复]

PySpark - 获取重复行的索引

如果有重复记录,则更新同一表的列

如果行不是重复的,或者行的 ID 不是 SQL SSMS 中的某个数字,则更新列