yk156511 发表于 2023-12-23 18:57

ORACLE数据库SQL语句

业务场景:
有表ZRZ;其中一个字段为dyh。

我首先通过了group by分组筛选出了dyh重复的数据。

例如 dyh为4880015551240000的有15条。
我想把这15条的dyh字段重新编号为 4880015551240001,4880015551240002。 一直到4880015551240015.(共15条)

简单的说就是前面的部分不变,只对最后两位改变。

我测试是不能用lpad(rownum)。因为这些重复的dyh提出来的rownum都不是连贯的1-15。

我的思路是写一个循环,先提出重复的,然后再来根据row_number 重排序后来拼接。
具体实施后我陷入瓶颈。具体执行他是把我所有的dyh都update成一样的了。
求一个方案。

dommy 发表于 2023-12-23 19:11

本帖最后由 dommy 于 2023-12-23 19:15 编辑

一定要在数据库里面实现么?可考虑结合excel处理

zyzs010 发表于 2023-12-23 19:47

很简单,查询出dyh重复的数据,同时查询rowid或者主键,及dyh+row_number作为新编号,作为一个子查询,用merge into去更新原表

wy192500 发表于 2023-12-23 20:24

先筛选,update指定dyh=这个值,让这个值+1,执行完执行这个值+2……一直执行下去,直到没有这个值。

zach14c 发表于 2023-12-24 21:42

如果要在一个SQL语句完成,必须借助package variable来记录状态,如下:
create or replace package ZZ_PKG as
FUNCTION inc_one return number;
end ZZ_PKG;

create or replace package BODY ZZ_PKG as
ss1 number := 0; function inc_one return number is
begin
ss1 := ss1 + 1; return ss1;
end inc_one;
end ZZ_PKG;

update zz01 c
   set field2 =
      (select substr(a.field2, 1, 14) || lpad(ZZ_PKG.inc_one(), 2, '0') as f3
         from ZZ01 a
          where c.field2 = a.field2
            and c.rowid = a.rowid)
where exists (select 'x'
          from (select count(field2) as f2_count, field2
                   from zz01
                  group by field2
               having count(field2) > 1) b
         where b.field2 = c.field2);

在Oracle上撰写PL/SQL会是比较直觉的解法

yk156511 发表于 2023-12-27 11:41

已解决
DECLARE
CURSOR Cur_Duplicates IS
    SELECT dyh FROM ZRZ GROUP BY dyh HAVING COUNT(*) > 1;
v_New_Id NUMBER := 1;
v_Prefix VARCHAR2(200);
BEGIN
FOR Dup_Record IN Cur_Duplicates LOOP
    v_Prefix := Substr(Dup_Record.dyh, 1, Length(Dup_Record.dyh) - 2);
    FOR Rec IN (SELECT ROWID, dyh FROM ZRZ WHERE dyh = Dup_Record.dyh ORDER BY ROWID) LOOP
      UPDATE ZRZ SET dyh = v_Prefix || Lpad(v_New_Id, 2, '0') WHERE ROWID = Rec.Rowid;
      v_New_Id := v_New_Id + 1;
    END LOOP;
    v_New_Id := 1; -- 重新设置为1,以便下一个重复记录集使用
END LOOP;
END;
页: [1]
查看完整版本: ORACLE数据库SQL语句