Предполагая, что значения ID2 должны быть в том же порядке, что и значения ID1, и нет повторяющихся значений ID1, вы можете сделать это без последовательности, используя аналитические функции с подходящими предложениями окна:
select name, dob, id1,
100 + dense_rank() over (order by trunc(id1))
+ dense_rank() over (partition by trunc(id1) order by id1)/10
as id2
from table1;
NAME DOB ID1 ID2
----- ---------- ---------- ----------
JIM 1991-11-30 23.1 101.1
JIM 1991-11-30 23.2 101.2
JIM 1991-11-30 23.3 101.3
TOM 1993-12-30 30.1 102.1
TOM 1993-12-30 30.2 102.2
HENRY 1994-12-03 34.1 103.1
HENRY 1994-12-03 34.2 103.2
7 rows selected.
Затем вы можете использовать эту сгенерированную таблицу как часть оператора слияния:
merge into table1
using (
select name, dob, id1,
100 + dense_rank() over (order by trunc(id1))
+ dense_rank() over (partition by trunc(id1) order by id1)/10
as id2
from table1
) tmp on (tmp.id1 = table1.id1)
when matched then
update set table1.id2 = tmp.id2;
7 rows merged.
select * from table1;
NAME DOB ID1 ID2
----- ---------- ---------- ----------
JIM 1991-11-30 23.1 101.1
JIM 1991-11-30 23.2 101.2
JIM 1991-11-30 23.3 101.3
TOM 1993-12-30 30.1 102.1
TOM 1993-12-30 30.2 102.2
HENRY 1994-12-03 34.1 103.1
HENRY 1994-12-03 34.2 103.2
7 rows selected.
db <> fiddle
Если ID2 не нужнобыть связанным с ID1, вы можете заказать по своему усмотрению:
merge into table1
using (
select name, dob, id1,
100 + dense_rank() over (order by name, dob)
+ dense_rank() over (partition by name, dob order by id1)/10
as id2
from table1
) tmp on (tmp.id1 = table1.id1)
when matched then
update set table1.id2 = tmp.id2;
select * from table1;
NAME DOB ID1 ID2
----- ---------- ---------- ----------
JIM 1991-11-30 23.1 102.1
JIM 1991-11-30 23.2 102.2
JIM 1991-11-30 23.3 102.3
TOM 1993-12-30 30.1 103.1
TOM 1993-12-30 30.2 103.2
HENRY 1994-12-03 34.1 101.1
HENRY 1994-12-03 34.2 101.2
Это будет работать как есть, только если десятичная дробь не будет больше 0,9;но тогда было бы трудно интерпретировать значения, если бы это произошло (поскольку 23.10 - это то же самое, что и 23.1).
Я также предполагаю, что это разовое обновление, и вы не• планируют использовать последовательность для будущих вставок;непонятно, как бы вы справились с этим - вы бы хотели получить следующее значение последовательности, только если имя / DOB еще не существует, и если бы они это сделали, вам нужно было бы найти самый высокий существующий идентификатор и добавить к нему 0,1,В любом случае вам нужно было бы сериализовать вставки для предотвращения столкновений или расхождений.
это фактически привело к ситуации, когда значение ID1 было 23,10, 23,11, а ID2 отображало их как 101,1, 101,1.... Я попытался разделить его на 100, и проблема была решена для значения> = .11 десятичных знаков, но для .10 и .20 он по-прежнему отображается как .1 & .2.
Это говорит о том, чтооба значения ID являются строковыми, а не числами.Если это так, вы все равно можете использовать функции ранжирования, но обрабатывать два сгенерированных числа как строки и объединять их вместе:
merge into table1
using (
select name, dob, id1,
to_char(100 + dense_rank() over (order by name, dob))
||'.'||
dense_rank() over (partition by name, dob
order by to_number(substr(id1, instr(id1, '.') + 1)))
as id2
from table1
) tmp on (tmp.id1 = table1.id1)
when matched then
update set table1.id2 = tmp.id2;
With some additional base data that gives you:
select * from table1;
NAME DOB ID1 ID2
----- ---------- ---------- ----------
JIM 1991-11-30 23.1 103.1
JIM 1991-11-30 23.2 103.2
JIM 1991-11-30 23.3 103.3
TOM 1993-12-30 30.1 104.1
TOM 1993-12-30 30.3 104.2
HENRY 1993-12-30 34.1 101.1
HENRY 1994-12-03 34.5 102.1
HENRY 1994-12-03 34.6 102.2
HENRY 1994-12-03 34.7 102.3
HENRY 1994-12-03 34.8 102.4
HENRY 1994-12-03 34.9 102.5
HENRY 1994-12-03 34.10 102.6
HENRY 1994-12-03 34.11 102.7
HENRY 1994-12-03 34.12 102.8
HENRY 1994-12-03 34.13 102.9
HENRY 1994-12-03 34.14 102.10
HENRY 1994-12-03 34.15 102.11
HENRY 1994-12-03 34.16 102.12
db <> fiddle
Конечно,выполнение этого делает невозможным очень неудобное обращение со значениями ID2 как с числами или их упорядоченное упорядочение;но тогда это должно иметь место уже для ваших значений ID1.В качестве альтернативы можно вместо этого умножить первую часть на большое число, скажем, 1000, а затем добавить вторую часть, чтобы Генри закончил с 1020001 до 1010012.