我有这张表,其中包含以下记录:
表1
id ele_id_1 ele_val ele_id_2
1 2 123 1
1 1 abc 1
1 4 xyz 2
1 4 456 1
2 5 22 1
2 4 344 1
2 3 6 1
2 2 Test Name 1
2 1 Hello 1
当ASC对id
和ele_id_1
进行订购时,我试图为每个ele_id_2
添加头寸。
以下是输出:
id ele_id_1 ele_val ele_id_2 position
1 2 123 1 2
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 3
2 5 22 1 5
2 4 344 1 4
2 3 6 1 3
2 2 Test Name 1 2
2 1 Hello 1 1
我在表1中有3400万行,因此想使用一种有效的方法来实现这一点。
关于如何添加位置值的任何想法?
答案 0 :(得分:3)
我认为您希望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
编辑:
如果您要更新数据,那么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;
但是,如果您截断该表,请非常小心。请务必先备份它!