Я думаю, вы хотите row_number()
использовать так:
select row_number() over (partition by id
order by ele_id_1, ele_id_2
) as position
Oracle может использовать индекс для этого на (id, ele_id_1, ele_id_2)
.
Следует отметить, что для вашего примера данные order by ele_id_1, ele_id_2
и order by ele_id_2, ele_id_1
дают одинаковый результат. Ваш вопрос предполагает, что вы хотите первый.
Итак, вы получите
id ele_id_1 ele_val ele_id_2 position
1 1 123 2 2
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 3
Вместо:
id ele_id_1 ele_val ele_id_2 position
1 1 123 2 3
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 2
EDIT:
Если вы хотите обновить данные, тогда merge
, вероятно, лучший подход.
MERGE INTO <yourtable> dest
USING (select t.*,
row_number() over (partition by id
order by ele_id_1, ele_id_2
) as new_position
from <yourtable> t
) src
ON dest.id = src.id AND
dest.ele_id_1 = src.ele_id_1 AND
dest.ele_id_2 = src.ele_id_2
WHEN MATCHED THEN UPDATE
SET desc.postition = src.new_position;
Обратите внимание, что обновление всех строк в таблице является дорогостоящей операцией. Усечение таблицы и ее воссоздание может быть проще:
create table temp_t as
select t.*,
row_number() over (partition by id
order by ele_id_1, ele_id_2
) as new_position
from t;
truncate table t;
insert into t ( . . . )
select . . . -- all columns but position
from temp_t;
Однако будьте очень осторожны, если вы урежете таблицу. Обязательно сначала сделайте резервную копию!