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:15 编辑
一定要在数据库里面实现么?可考虑结合excel处理 很简单,查询出dyh重复的数据,同时查询rowid或者主键,及dyh+row_number作为新编号,作为一个子查询,用merge into去更新原表 先筛选,update指定dyh=这个值,让这个值+1,执行完执行这个值+2……一直执行下去,直到没有这个值。 如果要在一个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会是比较直觉的解法 已解决
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]