用于使用序列消除重复条目的 Oracle PLSQL 更新查询

Posted

技术标签:

【中文标题】用于使用序列消除重复条目的 Oracle PLSQL 更新查询【英文标题】:Oracle PLSQL update query for eliminating duplicate entries using sequence 【发布时间】:2020-10-05 09:40:10 【问题描述】:

我在 oracle 数据库 (plsql) 的表事件中有一个列 ref_key,其中 ref_key 我是从 creation_time 格式生成的

update events set ref_key= 'EV_'|| TOCHAR(creation_time, 'YYMMDD_HH24MISS');

现在的问题是事件是由文件中的批次生成的,因此许多行的创建时间可以相同。此列中可能有任意数量的重复项,我希望它是唯一的。 我已经有一个主键,这是最近添加的非 id 字段,需要更新现有数据以在此 ref_key 列中具有唯一的非空人类可读值。 我正在获取像 A 列这样的数据,我想要它像 B 列一样

Column A                      Column B                         or 
EV_201005_151610              EV_201005_151610                 EV_201005_151610_1
EV_201005_151610              EV_201005_151610_1               EV_201005_151610_2
EV_201005_151610              EV_201005_151610_2               EV_201005_151610_3
EV_201005_151610              EV_201005_151610_3               EV_201005_151610_4
EV_201005_151610              EV_201005_151610_4               EV_201005_151610_5
EV_201005_151711              EV_201005_151711                 EV_201005_151711_1
EV_201005_151711              EV_201005_151711_1               EV_201005_151711_2
EV_201005_151711              EV_201005_151711_2               EV_201005_151711_3

我不知道该怎么做。我可以获得 ref_key where count(ref_key) > 1 的所有不同值。然后可以附加一些序列并在值更改后重置序列,或类似的东西。或者可能是我的第一个更新查询本身。任何人都可以帮助查询以实现此目标。

【问题讨论】:

【参考方案1】:

如果你有一个主键列,比如id,你可以使用merge 语句来做到这一点:

merge into events e
using (
    select 
        id, 
        row_number() over(partition by to_char(creation_time, 'YYMMDD_HH24MISS') order by id) rn,
        count(*)     over(partition by to_char(creation_time, 'YYMMDD_HH24MISS')) cnt
    from events
) e1
on (e1.id = e.id)
when matched then 
    update set e.ref_key = 'EV_' 
        || to_char(creation_time, 'YYMMDD_HH24MISS') 
        || case when e1.cnt > 1 then '_' || to_char(e1.rn) end

Demo on DB Fiddle

样本数据:

身份证 |创建时间 | REF_KEY -: | :----------------- | :------ 1 | 2020-10-05 11:03:57 | 2 | 2020-10-05 11:03:57 | 3 | 2020-10-04 11:03:57 | 4 | 2020-10-04 11:03:57 | 5 | 2020-10-04 11:03:57 | 6 | 2020-10-03 11:03:57 |

结果:

身份证 |创建时间 | REF_KEY -: | :----------------- | :----------------- 1 | 2020-10-05 11:03:57 | EV_201005_110357_1 2 | 2020-10-05 11:03:57 | EV_201005_110357_2 3 | 2020-10-04 11:03:57 | EV_201004_110357_1 4 | 2020-10-04 11:03:57 | EV_201004_110357_2 5 | 2020-10-04 11:03:57 | EV_201004_110357_3 6 | 2020-10-03 11:03:57 | EV_201003_110357

【讨论】:

以上是关于用于使用序列消除重复条目的 Oracle PLSQL 更新查询的主要内容,如果未能解决你的问题,请参考以下文章

消除链接到查询结果的重复表单条目

在 Oracle 11g 中过滤掉报告中的重复条目

oracle查询出来的数据如何消除重复数据

PLsq developer 只能连接ORACLE数据库么

维护序列项顺序的同时消除重复项

PLSQL远程连接Oracle报连接超时,PLSQ本地连接Oracle正常时怎么回事,请大侠给说一下