使用序列消除重复条目的 Oracle PLSQL 更新查询
Oracle PLSQL update query for eliminating duplicate entries using sequence
我在 Oracle 数据库 (plsql) 的 table 事件中有一列 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
的所有不同值。然后可以向其附加一些序列并在值更改后重置序列,或类似的事情。或者可能是我的第一个更新查询本身。任何人都可以帮助查询以实现此 objective.
如果你有一个主键列,比如说 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
示例数据:
ID | CREATION_TIME | REF_KEY
-: | :------------------ | :------
1 | 2020-10-05 11:03:57 | null
2 | 2020-10-05 11:03:57 | null
3 | 2020-10-04 11:03:57 | null
4 | 2020-10-04 11:03:57 | null
5 | 2020-10-04 11:03:57 | null
6 | 2020-10-03 11:03:57 | null
结果:
ID | CREATION_TIME | 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) 的 table 事件中有一列 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
的所有不同值。然后可以向其附加一些序列并在值更改后重置序列,或类似的事情。或者可能是我的第一个更新查询本身。任何人都可以帮助查询以实现此 objective.
如果你有一个主键列,比如说 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
示例数据:
ID | CREATION_TIME | REF_KEY -: | :------------------ | :------ 1 | 2020-10-05 11:03:57 | null 2 | 2020-10-05 11:03:57 | null 3 | 2020-10-04 11:03:57 | null 4 | 2020-10-04 11:03:57 | null 5 | 2020-10-04 11:03:57 | null 6 | 2020-10-03 11:03:57 | null
结果:
ID | CREATION_TIME | 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